├── .gitignore ├── .gitmodules ├── .readthedocs.yaml ├── .travis.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── Gruntfile.js ├── LICENSE ├── README.md ├── bower.json ├── browser ├── i18n │ ├── da_DK.js │ ├── en_US.js │ └── gl_GL.js ├── index.js ├── modules │ ├── advancedInfo.js │ ├── anchor.js │ ├── api-bridge │ │ ├── Queue.js │ │ ├── constants.js │ │ └── index.js │ ├── backboneEvents.js │ ├── baseLayer.js │ ├── bindEvent.js │ ├── cloud.js │ ├── configSwitcher │ │ ├── components │ │ │ └── ConfigSwitcher.js │ │ └── index.js │ ├── connection.js │ ├── constants.js │ ├── crs.js │ ├── download.js │ ├── draw.js │ ├── drawLocales │ │ ├── advancedInfo.js │ │ └── draw.js │ ├── drawTools │ │ └── index.js │ ├── height.js │ ├── infoClick.js │ ├── init.js │ ├── layerTree │ │ ├── Download.js │ │ ├── LabelSettingToggle.js │ │ ├── LayerFilter.js │ │ ├── LayerFilterSubBlock.js │ │ ├── LayerSorting.js │ │ ├── LoadStrategyToggle.js │ │ ├── MarkupGenerator.js │ │ ├── MetaSettingForm.js │ │ ├── OfflineModeControlsManager.js │ │ ├── QueueStatisticsWatcher.js │ │ ├── constants.js │ │ ├── controls │ │ │ ├── AutocompleteControl.js │ │ │ ├── BooleanControl.js │ │ │ ├── DateControl.js │ │ │ ├── DatetimeControl.js │ │ │ ├── NumberControl.js │ │ │ ├── SelectControl.js │ │ │ ├── StringControl.js │ │ │ ├── TimeControl.js │ │ │ └── index.js │ │ ├── filterUtils.js │ │ ├── index.js │ │ └── utils.js │ ├── layers.js │ ├── legend.js │ ├── mapcontrols.js │ ├── measurements.js │ ├── meta.js │ ├── print.js │ ├── pushState.js │ ├── reset.js │ ├── search │ │ ├── danish.js │ │ └── google.js │ ├── serializeLayers.js │ ├── setBaseLayer.js │ ├── setting.js │ ├── shared │ │ └── LoadingOverlay.js │ ├── socketId.js │ ├── sqlQuery.js │ ├── state.js │ ├── stateSnapshots │ │ ├── README.md │ │ ├── components │ │ │ ├── StateSnapshotsDashboard.js │ │ │ ├── TagComponent.js │ │ │ └── TitleFieldComponent.js │ │ └── index.js │ ├── switchLayer.js │ ├── tileCache.js │ ├── urlparser.js │ ├── utils.js │ └── utmZone.js └── service-worker │ ├── cache.development.js │ ├── cache.production.js │ └── index.js ├── config ├── config.embed.dist.js └── config.travis.js ├── controllers ├── config.js ├── css.js ├── df.js ├── gc2 │ ├── baseLayer.js │ ├── bulk.js │ ├── config.js │ ├── elasticsearch.js │ ├── feature.js │ ├── keyValue.js │ ├── legend.js │ ├── meta.js │ ├── setting.js │ ├── shared.js │ ├── sql.js │ ├── stateSnapshots.js │ └── wms.js ├── headlessBrowserPool.js ├── index.js ├── locale.js ├── mergePrint.js ├── print.js ├── static.js └── template.js ├── docker ├── base │ ├── Dockerfile │ └── conf │ │ └── supervisor │ │ └── supervisord.conf ├── docker-compose.yml └── stable │ ├── Dockerfile │ └── conf │ └── vidi │ └── config.js ├── docs ├── _media │ ├── baselayer-drawer.png │ ├── cross-multi-select.png │ ├── draw-create-line.png │ ├── draw-create-polygon.png │ ├── draw-edit.png │ ├── draw-linestyle.png │ ├── draw-list.png │ ├── draw-on.png │ ├── extensions-directions-icon.png │ ├── feature-info-table-on-map.png │ ├── filter-autocomplete.png │ ├── gc2-meta-editor.png │ ├── gc2-meta-filters.png │ ├── gc2-meta-filters2.png │ ├── gc2-meta-references.png │ ├── gc2-meta.png │ ├── gettingstarted-controls.png │ ├── gettingstarted-main.png │ ├── gettingstarted-menu.png │ ├── json-refs.png │ ├── layer-search.png │ ├── measure-create-area.png │ ├── measure-create-line.png │ ├── measure-edit.png │ ├── measure-on.png │ ├── meow.jpg │ ├── print-complete.png │ ├── print-on.png │ ├── print-ready.png │ ├── project-on.png │ ├── responsive-sidebar-collapsed.png │ ├── responsive-sidebar-expanded.png │ ├── sidebar-collapsed.png │ ├── sidebar-expanded.png │ ├── structur-tab-properties.png │ ├── structure-overview.png │ ├── vector-table.png │ └── vidi-responsive.png ├── _subs │ ├── CHANGELOG.rst │ ├── CONTRIBUTING.rst │ ├── GIT.rst │ ├── NOTE_CONF.rst │ ├── NOTE_GETTINGSTARTED.rst │ ├── README.rst │ └── WARNING_OLD_DOC.rst ├── conf.py ├── index.rst ├── locales │ └── en │ │ └── LC_MESSAGES │ │ ├── _subs.po │ │ ├── _subs │ │ ├── CHANGELOG.po │ │ ├── CONTRIBUTING.po │ │ ├── GIT.po │ │ ├── NOTE_CONF.po │ │ ├── NOTE_GETTINGSTARTED.po │ │ ├── README.po │ │ └── WARNING_OLD_DOC.po │ │ ├── index.po │ │ ├── pages.po │ │ └── pages │ │ ├── extensions │ │ ├── extensions.po │ │ └── non_standard.po │ │ ├── gettingstarted │ │ └── gettingstarted.po │ │ └── standard │ │ ├── 00_measure.po │ │ ├── 05_draw.po │ │ ├── 06_project.po │ │ ├── 07_print.po │ │ ├── 80_standard_query_string.po │ │ ├── 90_build_configuration.po │ │ ├── 91_run_configuration.po │ │ ├── 92_gc2_meta_information.po │ │ ├── 95_embed.po │ │ └── 96_api.po ├── pages │ ├── extensions │ │ ├── extensions.rst │ │ └── non_standard.rst │ ├── gettingstarted │ │ └── gettingstarted.rst │ └── standard │ │ ├── 00_measure.rst │ │ ├── 05_draw.rst │ │ ├── 06_project.rst │ │ ├── 07_print.rst │ │ ├── 80_standard_query_string.rst │ │ ├── 90_build_configuration.rst │ │ ├── 91_run_configuration.rst │ │ ├── 92_gc2_meta_information.rst │ │ ├── 93_templates.rst │ │ ├── 95_embed.rst │ │ └── 96_api.rst └── requirements.txt ├── extensions ├── conflictSearch │ ├── browser │ │ ├── controller.js │ │ ├── index.js │ │ ├── infoClick.js │ │ ├── reportRender.js │ │ └── reportRenderAlt.js │ ├── server │ │ └── index.js │ └── templates │ │ └── _conflictPrint.tmpl ├── coordinates │ └── browser │ │ └── index.js ├── directions │ └── browser │ │ └── index.js ├── editor │ └── browser │ │ ├── FileUploadWidget.js │ │ ├── SelectWidget.jsx │ │ ├── SelectWidget.tsx │ │ ├── TimeWidget.jsx │ │ ├── TimeWidget.tsx │ │ └── index.js ├── embed │ ├── browser │ │ └── index.js │ └── templates │ │ └── embed.tmpl ├── index.js ├── languages │ └── browser │ │ └── index.js ├── offlineMap │ └── browser │ │ ├── CachedAreasManager.js │ │ ├── components │ │ ├── LoadingOverlay.js │ │ ├── MapAreaList.js │ │ └── MapAreaListItem.js │ │ └── index.js ├── session │ ├── browser │ │ └── index.js │ └── server │ │ └── index.js ├── streetView │ └── browser │ │ └── index.js └── symbols │ ├── browser │ └── index.js │ ├── script │ └── parse.py │ └── server │ └── index.js ├── index.js ├── karma.config.js ├── package-lock.json ├── package.json ├── public ├── api │ └── config │ │ ├── aleksandrshumilov │ │ └── aleksandrshumilov.json │ │ └── vidi.json ├── browserconfig.xml ├── connection-check.ico ├── css │ └── webfonts │ │ ├── fa-brands-400.eot │ │ ├── fa-brands-400.svg │ │ ├── fa-brands-400.ttf │ │ ├── fa-brands-400.woff │ │ ├── fa-brands-400.woff2 │ │ ├── fa-regular-400.eot │ │ ├── fa-regular-400.svg │ │ ├── fa-regular-400.ttf │ │ ├── fa-regular-400.woff │ │ ├── fa-regular-400.woff2 │ │ ├── fa-solid-900.eot │ │ ├── fa-solid-900.svg │ │ ├── fa-solid-900.ttf │ │ ├── fa-solid-900.woff │ │ ├── fa-solid-900.woff2 │ │ ├── fa-v4compatibility.ttf │ │ └── fa-v4compatibility.woff2 ├── favicon.ico.default ├── fonts │ ├── bootstrap-icons.svg │ ├── cJZKeOuBrn4kERxqtaUH3bO3LdcAZYWl9Si6vvxL-qU.woff │ ├── fa-regular-400.svg │ ├── fa-regular-400.ttf │ ├── fa-regular-400.woff │ ├── fa-regular-400.woff2 │ ├── fa-solid-900.eot │ ├── fa-solid-900.svg │ ├── fa-solid-900.ttf │ ├── fa-solid-900.woff │ ├── fa-solid-900.woff2 │ ├── fontawesome-webfont.ttf │ ├── fontawesome-webfont.woff │ ├── fontawesome-webfont.woff2 │ ├── fonts.css │ ├── roboto-v18-latin-300.eot │ ├── roboto-v18-latin-300.svg │ ├── roboto-v18-latin-300.ttf │ ├── roboto-v18-latin-300.woff │ ├── roboto-v18-latin-300.woff2 │ ├── roboto-v18-latin-500.eot │ ├── roboto-v18-latin-500.svg │ ├── roboto-v18-latin-500.ttf │ ├── roboto-v18-latin-500.woff │ ├── roboto-v18-latin-500.woff2 │ ├── roboto-v18-latin-700.eot │ ├── roboto-v18-latin-700.svg │ ├── roboto-v18-latin-700.ttf │ ├── roboto-v18-latin-700.woff │ ├── roboto-v18-latin-700.woff2 │ ├── roboto-v18-latin-900.eot │ ├── roboto-v18-latin-900.svg │ ├── roboto-v18-latin-900.ttf │ ├── roboto-v18-latin-900.woff │ ├── roboto-v18-latin-900.woff2 │ ├── roboto-v18-latin-italic.eot │ ├── roboto-v18-latin-italic.svg │ ├── roboto-v18-latin-italic.ttf │ ├── roboto-v18-latin-italic.woff │ ├── roboto-v18-latin-italic.woff2 │ ├── roboto-v18-latin-regular.eot │ ├── roboto-v18-latin-regular.svg │ ├── roboto-v18-latin-regular.ttf │ ├── roboto-v18-latin-regular.woff │ └── roboto-v18-latin-regular.woff2 ├── images │ ├── 192x192.png │ ├── 48x48.png │ ├── 512x512.png │ ├── favicon-16x16.png │ └── favicon-32x32.png ├── index.html.default ├── js │ ├── embed.js │ ├── gc2 │ │ ├── gc2table.js │ │ └── geocloud.js │ ├── lib │ │ ├── Leaflet.GridLayer.GoogleMutant │ │ │ └── Leaflet.GoogleMutant.js │ │ ├── Leaflet.NonTiledLayer │ │ │ └── NonTiledLayer.js │ │ ├── Leaflet.awesome-markers │ │ │ ├── images │ │ │ │ ├── markers-matte.png │ │ │ │ ├── markers-matte@2x.png │ │ │ │ ├── markers-plain.png │ │ │ │ ├── markers-shadow.png │ │ │ │ ├── markers-shadow@2x.png │ │ │ │ ├── markers-soft.png │ │ │ │ └── markers-soft@2x.png │ │ │ ├── leaflet.awesome-markers.css │ │ │ └── leaflet.awesome-markers.js │ │ ├── Leaflet.extra-markers │ │ │ ├── css │ │ │ │ └── leaflet.extra-markers.css │ │ │ ├── img │ │ │ │ ├── markers_default.png │ │ │ │ ├── markers_default@2x.png │ │ │ │ ├── markers_shadow.png │ │ │ │ └── markers_shadow@2x.png │ │ │ ├── leaflet.extra-markers.js │ │ │ └── leaflet.extra-markers.less │ │ ├── Leaflet.markercluster │ │ │ ├── MarkerCluster.Default.css │ │ │ ├── MarkerCluster.css │ │ │ └── leaflet.markercluster.js │ │ ├── Leaflet.utfgrid │ │ │ ├── L.NonTiledUTFGrid.js │ │ │ ├── L.UTFGrid.js │ │ │ └── L.UTFGridCanvas.js │ │ ├── Path.Drag.js │ │ │ ├── .bower.json │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── example │ │ │ │ ├── canvas.html │ │ │ │ ├── index.html │ │ │ │ └── russia.html │ │ │ ├── package.json │ │ │ ├── src │ │ │ │ └── Path.Drag.js │ │ │ └── test │ │ │ │ ├── Path.Drag.js │ │ │ │ └── index.html │ │ ├── bootstrap-colorpicker │ │ │ ├── bootstrap-colorpicker.css │ │ │ ├── bootstrap-colorpicker.js │ │ │ ├── css │ │ │ │ ├── bootstrap-colorpicker.css │ │ │ │ ├── bootstrap-colorpicker.css.map │ │ │ │ ├── bootstrap-colorpicker.min.css │ │ │ │ └── bootstrap-colorpicker.min.css.map │ │ │ ├── img │ │ │ │ └── bootstrap-colorpicker │ │ │ │ │ ├── alpha-horizontal.png │ │ │ │ │ ├── alpha.png │ │ │ │ │ ├── hue-horizontal.png │ │ │ │ │ ├── hue.png │ │ │ │ │ └── saturation.png │ │ │ └── js │ │ │ │ ├── bootstrap-colorpicker.js │ │ │ │ └── bootstrap-colorpicker.min.js │ │ ├── hogan.js │ │ │ ├── hogan-3.0.2.js │ │ │ └── hogan.js │ │ ├── jquery.canvasResize.js │ │ │ ├── jquery.canvasResize.js │ │ │ └── jquery.exif.js │ │ ├── leaflet-boxzoom │ │ │ ├── leaflet-boxzoom-src.js │ │ │ ├── leaflet-boxzoom.css │ │ │ ├── leaflet-boxzoom.js │ │ │ └── leaflet-boxzoom.svg │ │ ├── leaflet-dash-flow │ │ │ └── L.Path.DashFlow.js │ │ ├── leaflet-draw │ │ │ ├── images │ │ │ │ ├── layers-2x.png │ │ │ │ ├── layers.png │ │ │ │ ├── marker-icon-2x.png │ │ │ │ ├── marker-icon.png │ │ │ │ ├── marker-shadow.png │ │ │ │ ├── spritesheet-2x.png │ │ │ │ ├── spritesheet.png │ │ │ │ └── spritesheet.svg │ │ │ ├── leaflet.draw-src.css │ │ │ ├── leaflet.draw-src.js │ │ │ ├── leaflet.draw-src.map │ │ │ ├── leaflet.draw.css │ │ │ ├── leaflet.draw.js │ │ │ ├── spritesheet-2x.png │ │ │ ├── spritesheet.png │ │ │ └── spritesheet.svg │ │ ├── leaflet-geometryutil │ │ │ └── leaflet.geometryutil.js │ │ ├── leaflet-glify │ │ │ ├── glify-browser.js │ │ │ ├── glify-browser.js.map │ │ │ ├── glify.js │ │ │ └── glify.js.map │ │ ├── leaflet-history │ │ │ ├── leaflet-history.css │ │ │ └── leaflet-history.js │ │ ├── leaflet-measure-path │ │ │ ├── leaflet-measure-path.css │ │ │ └── leaflet-measure-path.js │ │ ├── leaflet-measure │ │ │ ├── images │ │ │ │ ├── cancel.png │ │ │ │ ├── cancel_@2X.png │ │ │ │ ├── check.png │ │ │ │ ├── check_@2X.png │ │ │ │ ├── focus.png │ │ │ │ ├── focus_@2X.png │ │ │ │ ├── rulers.png │ │ │ │ ├── rulers_@2X.png │ │ │ │ ├── start.png │ │ │ │ ├── start_@2X.png │ │ │ │ ├── trash.png │ │ │ │ └── trash_@2X.png │ │ │ ├── leaflet-measure.css │ │ │ ├── leaflet-measure.js │ │ │ └── leaflet-measure.min.js │ │ ├── leaflet-plugins │ │ │ ├── Bing.js │ │ │ ├── GPX.Speed.js │ │ │ ├── GPX.js │ │ │ ├── Icon.Canvas.js │ │ │ ├── KML.js │ │ │ ├── Layer.Deferred.js │ │ │ ├── Layers.Load.js │ │ │ ├── Marker.Rotate.js │ │ │ ├── Marker.Text.js │ │ │ ├── OSM.js │ │ │ ├── Permalink.Layer.js │ │ │ ├── Permalink.Line.js │ │ │ ├── Permalink.Marker.js │ │ │ ├── Permalink.Overlay.js │ │ │ ├── Permalink.js │ │ │ ├── TOPOJSON.js │ │ │ └── Yandex.js │ │ ├── leaflet-side-by-side │ │ │ ├── .npmignore │ │ │ ├── CHANGELOG.md │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── index.js │ │ │ ├── layout.css │ │ │ ├── leaflet-side-by-side.js │ │ │ ├── leaflet-side-by-side.min.js │ │ │ ├── package.json │ │ │ ├── range-icon.png │ │ │ ├── range.css │ │ │ └── screencast.gif │ │ ├── leaflet-simple-map-screenshoter │ │ │ └── dist │ │ │ │ ├── leaflet-simple-map-screenshoter.js │ │ │ │ └── leaflet-simple-map-screenshoter.js.map │ │ ├── leaflet-snap │ │ │ └── leaflet.snap.js │ │ ├── leaflet-vector-grid │ │ │ ├── Leaflet.VectorGrid.bundled.js │ │ │ ├── Leaflet.VectorGrid.bundled.js.map │ │ │ ├── Leaflet.VectorGrid.bundled.min.js │ │ │ ├── Leaflet.VectorGrid.js │ │ │ ├── Leaflet.VectorGrid.js.map │ │ │ └── Leaflet.VectorGrid.min.js │ │ ├── leaflet.editable │ │ │ └── Leaflet.Editable.js │ │ ├── leaflet.locatecontrol │ │ │ ├── L.Control.Locate.css │ │ │ └── L.Control.Locate.js │ │ ├── leaflet.tilelayer.wmts │ │ │ └── leaflet.tilelayer.wmts.src.js │ │ ├── leaflet.toolbar │ │ │ ├── leaflet.toolbar.css │ │ │ └── leaflet.toolbar.js │ │ ├── leaflet │ │ │ ├── images │ │ │ │ ├── layers-2x.png │ │ │ │ ├── layers.png │ │ │ │ ├── marker-icon-2x.png │ │ │ │ ├── marker-icon.png │ │ │ │ └── marker-shadow.png │ │ │ ├── leaflet-src.esm.js │ │ │ ├── leaflet-src.esm.js.map │ │ │ ├── leaflet-src.js │ │ │ ├── leaflet-src.js.map │ │ │ ├── leaflet.css │ │ │ ├── leaflet.js │ │ │ └── leaflet.js.map │ │ ├── localforage │ │ │ └── localforage.js │ │ ├── snackbarjs │ │ │ └── snackbar.min.css │ │ ├── tableExport.jquery.plugin │ │ │ └── tableExport.js │ │ └── typeahead.js │ │ │ ├── typeahead.bundle.js │ │ │ └── typeahead.jquery.js │ └── vidi.js ├── less │ ├── styles.default.less │ └── styles.less ├── templates │ └── standard │ │ ├── blank.tmpl │ │ ├── conflict.tmpl │ │ ├── default.tmpl │ │ ├── min.tmpl │ │ └── print.tmpl ├── tmp │ ├── excel │ │ └── .gitignore │ ├── print │ │ ├── json │ │ │ └── .gitignore │ │ ├── pdf │ │ │ └── .gitignore │ │ └── png │ │ │ └── .gitignore │ └── stored_results │ │ └── .gitignore └── version.json ├── scss ├── custom.scss ├── main.scss ├── styles.scss └── themes.scss ├── test ├── README.md ├── api │ ├── keyValueProxy.test.js │ ├── stateSnapshotManagement.test.js │ └── static.test.js ├── config │ ├── aleksandrshumilov │ │ ├── aleksandrshumilov.json │ │ ├── aleksandrshumilov_baselayers.json │ │ ├── aleksandrshumilov_baselayers_with_GC2.json │ │ ├── aleksandrshumilov_baselayers_without_GC2.json │ │ └── aleksandrshumilov_with_startup_modal.json │ ├── regression │ │ ├── html_test_default │ │ │ └── config │ │ │ │ └── config.js │ │ ├── html_test_embed │ │ │ └── config │ │ │ │ └── config.js │ │ ├── html_test_latest_gc2 │ │ │ └── config │ │ │ │ └── config.js │ │ └── nginx_config │ │ │ └── nginx.conf │ └── vidi.json ├── helpers.js ├── nginx.conf ├── puppeteer │ ├── application.test.js │ ├── baseLayer.test.js │ ├── bootstrap.js │ ├── draw.test.js │ ├── editor.test.js │ ├── infoClick.test.js │ ├── layerTree │ │ ├── filters.test.js │ │ ├── index.test.js │ │ ├── loadStrategy.test.js │ │ ├── opacity.test.js │ │ ├── tableView.test.js │ │ ├── types.test.js │ │ └── virtualLayers.test.js │ ├── measurements.test.js │ ├── offlineMap.test.js │ ├── print.test.js │ ├── session.test.js │ └── stateSnapshots.test.js └── unit │ └── queue.test.js └── tmp └── .gitignore /.gitmodules: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/.gitmodules -------------------------------------------------------------------------------- /.readthedocs.yaml: -------------------------------------------------------------------------------- 1 | # .readthedocs.yaml 2 | # Read the Docs configuration file 3 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details 4 | 5 | # Required 6 | version: 2 7 | 8 | # Set the version of Python and other tools you might need 9 | build: 10 | os: ubuntu-24.04 11 | tools: 12 | python: "latest" 13 | jobs: 14 | pre_build: 15 | - sphinx-build -b gettext ./docs ./docs/_build/gettext 16 | - sphinx-intl update -p ./docs/_build/gettext -l en 17 | 18 | # Build documentation in the docs/ directory with Sphinx 19 | sphinx: 20 | configuration: docs/conf.py 21 | 22 | # We recommend specifying your dependencies to enable reproducible builds: 23 | # https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html 24 | python: 25 | install: 26 | - requirements: docs/requirements.txt 27 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | before_script: 2 | - npm install -g grunt-cli 3 | - npm install 4 | - git submodule init 5 | - git submodule sync --recursive 6 | - git submodule update --init --recursive 7 | - cp config/config.travis.js config/config.js 8 | - cp public/js/lib/bootstrap-material-design/less/_variables.less config/_variables.less 9 | - cd ./extensions/keplergl/browser 10 | - echo $PATH 11 | - ./../../../node_modules/.bin/npm install 12 | - cd ../../.. 13 | - cd public/js/lib/bootstrap-material-design 14 | - ./../../../../node_modules/.bin/npm install 15 | - cd ../../../.. 16 | - grunt production 17 | language: node_js 18 | node_js: 19 | - "8" 20 | branches: 21 | only: 22 | - master 23 | - develop 24 | - testing 25 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vidi", 3 | "homepage": "https://github.com/mapcentia/vidi", 4 | "authors": [ 5 | "Martin Høgh " 6 | ], 7 | "description": "", 8 | "main": "", 9 | "license": "GPL", 10 | "ignore": [ 11 | "**/.*", 12 | "node_modules", 13 | "bower_components", 14 | "test", 15 | "tests" 16 | ], 17 | "dependencies": { 18 | "arrive": "^2.3.1", 19 | "bootstrap-colorpicker": "^2.5.1", 20 | "backbone": "^1.3.3", 21 | "bootstrap-material-datetimepicker": "^2.7.1", 22 | "bootstrap-material-design": "0.5.10", 23 | "bootstrap-select": "^1.12.4", 24 | "bootstrap-table": "^1.11.0", 25 | "hogan.js": "hogan#^3.0.2", 26 | "html2canvas": "*", 27 | "hyperform": "^0.9.6", 28 | "jspdf-autotable": "2.0.9 || 2.0.14", 29 | "leaflet-draw": "^1.0.2", 30 | "leaflet-measure-path": "^1.3.1", 31 | "leaflet-measure": "git://github.com/mapcentia/leaflet-measure.git#^2.0.2", 32 | "leaflet-plugins": "https://github.com/shramov/leaflet-plugins.git#^3.0.2", 33 | "Leaflet.awesome-markers": "https://github.com/lvoogdt/Leaflet.awesome-markers.git#^2.0.2", 34 | "leaflet.editable": "^1.1.0", 35 | "Leaflet.extra-markers": "^1.0.6", 36 | "Leaflet.GridLayer.GoogleMutant": "https://gitlab.com/IvanSanchez/Leaflet.GridLayer.GoogleMutant.git", 37 | "leaflet.locatecontrol": "https://github.com/domoritz/leaflet-locatecontrol.git#^0.62.0", 38 | "Leaflet.utfgrid": "https://github.com/danzel/Leaflet.utfgrid.git", 39 | "leaflet": "^1.3.1", 40 | "mustache.js": "mustache#^2.3.0", 41 | "Path.Drag.js": "https://github.com/Leaflet/Path.Drag.js.git#^0.0.6", 42 | "proj4": "^2.4.4", 43 | "raphael": "^2.2.7", 44 | "showdown": "^1.4.3", 45 | "snackbarjs": "^1.1.0", 46 | "tableExport.jquery.plugin": "^1.5.2", 47 | "typeahead.js": "0.10.5", 48 | "underscore": "^1.8.3", 49 | "jrespond": "https://github.com/ten1seven/jRespond.git#^1.0.0", 50 | "d3": "^4.13.0", 51 | "q-cluster": "https://github.com/spatialdev/q-cluster.git", 52 | "es5-shim": "^4.5.10", 53 | "localforage": "^1.6.0", 54 | "leaflet.toolbar": "https://github.com/mapcentia/Leaflet.toolbar.git#^0.3.0" 55 | }, 56 | "resolutions": { 57 | "jquery": "^2.2", 58 | "leaflet": "^1.3.1", 59 | "bootstrap-material-design": "0.5.10", 60 | "jspdf": "1.3.2 - 1.3.4" 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /browser/modules/api-bridge/constants.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Alexander Shumilov 3 | * @copyright 2013-2019 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | /** 8 | * API-Brdige constants 9 | */ 10 | 11 | const ONLINE_STATUS_CHECK_LIMIT = 5; 12 | const QUEUE_PROCESSING_INTERVAL = 5000; 13 | const QUEUE_STORE_NAME = 'vidi-feature-management-queue'; 14 | const QUEUE_DEFAULT_PKEY = `gid`; 15 | 16 | const LOG = false; 17 | 18 | const ADD_REQUEST = 0; 19 | const UPDATE_REQUEST = 1; 20 | const DELETE_REQUEST = 2; 21 | 22 | module.exports = { LOG, ONLINE_STATUS_CHECK_LIMIT, QUEUE_PROCESSING_INTERVAL, QUEUE_STORE_NAME, QUEUE_DEFAULT_PKEY, ADD_REQUEST, UPDATE_REQUEST, DELETE_REQUEST }; 23 | -------------------------------------------------------------------------------- /browser/modules/backboneEvents.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Martin Høgh 3 | * @copyright 2013-2018 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | 'use strict'; 8 | 9 | let Backbone = require('backbone'); 10 | let extend = require('lodash/extend'); 11 | 12 | /** 13 | * 14 | * @type {{}} 15 | */ 16 | var object = {}; 17 | 18 | module.exports = { 19 | set: function (o) { 20 | return this; 21 | }, 22 | init: function () { 23 | extend(object, Backbone.Events); 24 | 25 | }, 26 | get: function () { 27 | return object; 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /browser/modules/connection.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Martin Høgh 3 | * @copyright 2013-2018 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | 'use strict'; 8 | 9 | /** 10 | * 11 | */ 12 | 13 | 14 | module.exports = { 15 | getHost: function () { 16 | var host; 17 | 18 | host = window.gc2host; 19 | 20 | return host; 21 | } 22 | }; -------------------------------------------------------------------------------- /browser/modules/constants.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Martin Høgh 3 | * @copyright 2013-2022 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | /** 8 | * File contains constants that are used across the all modules 9 | */ 10 | 11 | const GEOJSON_PRECISION = 14; 12 | const MIME_TYPES_IMAGES = ['image/png', 'image/jpeg', 'image/gif']; 13 | const MIME_TYPES_APPS = [ 14 | 'application/pdf', 15 | 'text/plain', 16 | 'application/msword', 17 | 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 18 | 'application/vnd.oasis.opendocument.text', 19 | 'video/mp4', 20 | 'video/webm', 21 | 'video/ogg', 22 | 'audio/mpeg', 23 | 'audio/ogg', 24 | 'audio/wav', 25 | 'audio/aac', 26 | ] 27 | 28 | export { 29 | GEOJSON_PRECISION, MIME_TYPES_APPS, MIME_TYPES_IMAGES 30 | }; 31 | -------------------------------------------------------------------------------- /browser/modules/crs.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Martin Høgh 3 | * @copyright 2013-2025 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | 'use strict'; 8 | 9 | 10 | const resolutions = { 11 | EPSG3857: [156543.033928, 78271.516964, 39135.758482, 19567.879241, 9783.9396205, 12 | 4891.96981025, 2445.98490513, 1222.99245256, 611.496226281, 305.748113141, 152.87405657, 13 | 76.4370282852, 38.2185141426, 19.1092570713, 9.55462853565, 4.77731426782, 2.38865713391, 14 | 1.19432856696, 0.597164283478, 0.298582141739, 0.149291, 0.074645535, 0.037322767, 0.018661384, 15 | 0.009330692, 0.004665346, 0.002332673], 16 | EPSG25832: [1638.4, 819.2, 409.6, 204.8, 102.4, 51.2, 25.6, 12.8, 6.4, 3.2, 1.6, 0.8, 17 | 0.4, 0.2, 0.1, 0.05, 0.025, 0.0125, 0.00625, 0.002125] 18 | } 19 | 20 | const projections = { 21 | EPSG3857: L.CRS.EPSG3857, 22 | EPSG25832: new L.Proj.CRS('EPSG:25832', 23 | '+proj=utm +zone=32 +ellps=GRS80 +units=m +no_defs', { 24 | resolutions: resolutions.EPSG25832, 25 | origin: [120000, 6500000], 26 | bounds: L.bounds([120000, 5661139.2], [1378291.2, 6500000]) 27 | }), 28 | } 29 | 30 | const getProjection = (epsg = 'EPSG3857') => { 31 | return projections[epsg]; 32 | } 33 | 34 | const getResolutions = (epsg = 'EPSG3857') => { 35 | return resolutions[epsg]; 36 | } 37 | 38 | export {getProjection, getResolutions}; 39 | -------------------------------------------------------------------------------- /browser/modules/download.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Martin Høgh 3 | * @copyright 2013-2019 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | 'use strict'; 8 | 9 | /** 10 | * 11 | */ 12 | 13 | module.exports = { 14 | download: (sql, format) => { 15 | let request = new XMLHttpRequest(); 16 | request.open('POST', '/api/sql/' + db, true); 17 | request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charseselectt=UTF-8'); 18 | request.responseType = 'blob'; 19 | request.onload = function () { 20 | if (request.status === 200) { 21 | let filename, type; 22 | switch (format) { 23 | case "csv": 24 | filename = 'file.csv'; 25 | type = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'; 26 | break; 27 | case "excel": 28 | filename = 'file.xlsx'; 29 | type = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'; 30 | break; 31 | case "geojson": 32 | filename = 'file.geojson'; 33 | type = 'application/json'; 34 | break; 35 | default: 36 | filename = 'file.zip'; 37 | type = 'application/zip'; 38 | break; 39 | } 40 | let blob = new Blob([request.response], {type: type}); 41 | let link = document.createElement('a'); 42 | link.href = window.URL.createObjectURL(blob); 43 | link.download = filename; 44 | document.body.appendChild(link); 45 | link.click(); 46 | document.body.removeChild(link); 47 | } else { 48 | request.response.text().then(e => alert(JSON.parse(e).message.join("\n"))); 49 | } 50 | // some error handling should be done here... 51 | }; 52 | 53 | let uri = 'geoformat=wkt&format=' + format + '&client_encoding=UTF8&&srs=4326&q=' + sql; 54 | request.send(uri); 55 | } 56 | }; 57 | -------------------------------------------------------------------------------- /browser/modules/drawTools/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Martin Høgh 3 | * @copyright 2013-2021 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | /** 8 | * Common tools for drawing 9 | */ 10 | 11 | /** 12 | * Get readable distance of layer 13 | * @param e 14 | * @returns {string} 15 | * @private 16 | */ 17 | const getDistance = e => { 18 | let tempLatLng = null; 19 | let totalDistance = 0.00000; 20 | $.each(e._latlngs, function (i, latlng) { 21 | if (tempLatLng == null) { 22 | tempLatLng = latlng; 23 | return; 24 | } 25 | totalDistance += tempLatLng.distanceTo(latlng); 26 | tempLatLng = latlng; 27 | }); 28 | return L.GeometryUtil.readableDistance(totalDistance, true); 29 | }; 30 | 31 | /** 32 | * Get readable area of layer 33 | * @param e 34 | * @returns {string} 35 | * @private 36 | */ 37 | const getArea = e => { 38 | return L.GeometryUtil.readableArea(L.GeometryUtil.geodesicArea(e.getLatLngs()[0]), true); 39 | }; 40 | 41 | const getAreaOfCircle = e => { 42 | return L.GeometryUtil.readableArea(Math.pow(e.getRadius(), 2) * Math.PI, true); 43 | }; 44 | 45 | module.exports = { getDistance, getArea, getAreaOfCircle }; 46 | -------------------------------------------------------------------------------- /browser/modules/height.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Martin Høgh 3 | * @copyright 2013-2023 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | 'use strict'; 8 | 9 | /** 10 | * 11 | * @returns {*} 12 | */ 13 | module.exports = function () { 14 | try { 15 | var max = $(document).height() - $('.tab-pane').offset().top - 70; 16 | return { 17 | max: max 18 | } 19 | } catch (e) { 20 | console.info(e.message); 21 | return 0; 22 | } 23 | }; -------------------------------------------------------------------------------- /browser/modules/layerTree/Download.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Martin Høgh 3 | * @copyright 2013-2023 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | import React from 'react'; 8 | import PropTypes from 'prop-types'; 9 | 10 | class Download extends React.Component { 11 | constructor(props) { 12 | super(props); 13 | } 14 | handleDownload(e) { 15 | e.preventDefault(); 16 | const format = e.target.getAttribute("data-format"); 17 | this.props.onApplyDownload(this.props.layer.f_table_schema + `.` + this.props.layer.f_table_name, format); 18 | } 19 | 20 | render() { 21 | return ( 22 |
23 | 27 | 42 |
43 | ) 44 | } 45 | } 46 | 47 | Download.propTypes = { 48 | onApplyDownload: PropTypes.func.isRequired, 49 | layer: PropTypes.object.isRequired, 50 | }; 51 | 52 | export default Download; 53 | -------------------------------------------------------------------------------- /browser/modules/layerTree/LabelSettingToggle.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Martin Høgh 3 | * @copyright 2013-2022 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | import React from 'react'; 8 | import PropTypes from 'prop-types'; 9 | 10 | class LabelSettingToggle extends React.Component { 11 | constructor(props) { 12 | super(props); 13 | this.state = { checked: props.initialValue }; 14 | 15 | this.handleChange = this.handleChange.bind(this); 16 | } 17 | 18 | handleChange(event) { 19 | this.setState({ checked: event.target.checked }); 20 | this.props.onChange({ 21 | layerKey: this.props.layerKey, 22 | labelsAreEnabled: event.target.checked 23 | }); 24 | } 25 | 26 | render() { 27 | return (
28 |
29 | 30 | 31 |
32 |
) 33 | } 34 | } 35 | 36 | LabelSettingToggle.propTypes = { 37 | layerKey: PropTypes.string.isRequired, 38 | initialValue: PropTypes.bool.isRequired, 39 | onChange: PropTypes.func.isRequired, 40 | }; 41 | 42 | export default LabelSettingToggle; 43 | -------------------------------------------------------------------------------- /browser/modules/layerTree/LoadStrategyToggle.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Alexander Shumilov 3 | * @copyright 2013-2023 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | import React from 'react'; 8 | import PropTypes from 'prop-types'; 9 | 10 | class LoadStrategyToggle extends React.Component { 11 | constructor(props) { 12 | super(props); 13 | this.state = {checked: props.initialValue}; 14 | 15 | this.handleChange = this.handleChange.bind(this); 16 | } 17 | 18 | handleChange(event) { 19 | this.setState({checked: event.target.checked}); 20 | this.props.onChange({ 21 | layerKey: this.props.layerKey, 22 | dynamicLoadIsEnabled: event.target.checked 23 | }); 24 | } 25 | 26 | render() { 27 | return (
28 |
29 | 30 | 31 |
32 |
) 33 | } 34 | } 35 | 36 | LoadStrategyToggle.propTypes = { 37 | layerKey: PropTypes.string.isRequired, 38 | initialValue: PropTypes.bool.isRequired, 39 | onChange: PropTypes.func.isRequired, 40 | }; 41 | 42 | export default LoadStrategyToggle; 43 | -------------------------------------------------------------------------------- /browser/modules/layerTree/constants.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Alexander Shumilov 3 | * @copyright 2013-2019 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | /** 8 | * File contains constants that are used across the layerTree module 9 | */ 10 | 11 | const LOG = false; 12 | 13 | const MODULE_NAME = `layerTree`; 14 | 15 | const VIRTUAL_LAYERS_SCHEMA = `virtual_layer`; 16 | 17 | const SYSTEM_FIELD_PREFIX = `gc2_`; 18 | 19 | const SQL_QUERY_LIMIT = 100; 20 | 21 | const SUB_GROUP_DIVIDER = `|`; 22 | 23 | /** 24 | * Layer type prefixes 25 | */ 26 | const LAYER = { 27 | VECTOR: `v`, 28 | RASTER_TILE: `t`, 29 | VECTOR_TILE: `mvt`, 30 | WEBGL: `w` 31 | }; 32 | 33 | const LAYER_TYPE_DEFAULT = LAYER.RASTER_TILE; 34 | 35 | /** 36 | * Layer type icons 37 | */ 38 | let icons = {}; 39 | icons[LAYER.VECTOR] = ``; 40 | icons[LAYER.RASTER_TILE] = ``; 41 | icons[LAYER.VECTOR_TILE] = ``; 42 | icons[LAYER.WEBGL] = ``; 43 | const ICONS = icons; 44 | 45 | const VECTOR_SIDE_TABLE_EL = 'vector-side-table'; 46 | 47 | const SELECTED_STYLE = { 48 | opacity: 1, 49 | weight: 5, 50 | dashArray: "8 5", 51 | lineCap: "butt", 52 | } 53 | const VECTOR_STYLE = () => { 54 | return { 55 | opacity: 1, 56 | weight: 3, 57 | fillColor: "blue", 58 | color: "blue" 59 | } 60 | } 61 | 62 | const SELECTED_ICON_SCALE = 1.3; 63 | 64 | export { 65 | LOG, 66 | MODULE_NAME, 67 | VIRTUAL_LAYERS_SCHEMA, 68 | SYSTEM_FIELD_PREFIX, 69 | SQL_QUERY_LIMIT, 70 | LAYER, 71 | ICONS, 72 | LAYER_TYPE_DEFAULT, 73 | SUB_GROUP_DIVIDER, 74 | VECTOR_SIDE_TABLE_EL, 75 | SELECTED_STYLE, 76 | VECTOR_STYLE, 77 | SELECTED_ICON_SCALE, 78 | }; 79 | -------------------------------------------------------------------------------- /browser/modules/layerTree/controls/BooleanControl.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Alexander Shumilov 3 | * @copyright 2013-2018 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | import React from 'react'; 8 | import PropTypes from 'prop-types'; 9 | 10 | /** 11 | * Boolean control component 12 | */ 13 | class BooleanControl extends React.Component { 14 | constructor(props) { 15 | super(props); 16 | } 17 | 18 | render() { 19 | return (
20 |
21 | { this.props.onChange('null') }}/>{__(`Null`)} 23 |
24 |
25 | { this.props.onChange('true') }}/>{__(`Yes`)} 27 |
28 |
29 | { this.props.onChange('false') }}/>{__(`No`)} 31 |
32 |
); 33 | } 34 | } 35 | 36 | BooleanControl.propTypes = { 37 | id: PropTypes.string.isRequired, 38 | value: PropTypes.string.isRequired, 39 | onChange: PropTypes.func.isRequired, 40 | }; 41 | 42 | export { BooleanControl }; -------------------------------------------------------------------------------- /browser/modules/layerTree/controls/DateControl.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Alexander Shumilov 3 | * @copyright 2013-2023 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | import React from 'react'; 8 | import PropTypes from 'prop-types'; 9 | import dayjs from 'dayjs'; 10 | 11 | const FORMAT = `YYYY-MM-DD`; 12 | 13 | /** 14 | * Date control component 15 | */ 16 | class DateControl extends React.Component { 17 | constructor(props) { 18 | super(props); 19 | dayjs().locale(navigator.language.indexOf(`da_`) === 0 ? "da" : "en"); 20 | } 21 | 22 | render() { 23 | return ( { this.props.onChange(event.target.value) }}/>); 30 | } 31 | } 32 | 33 | DateControl.propTypes = { 34 | id: PropTypes.string.isRequired, 35 | value: PropTypes.string.isRequired, 36 | onChange: PropTypes.func.isRequired, 37 | }; 38 | 39 | export { DateControl }; 40 | -------------------------------------------------------------------------------- /browser/modules/layerTree/controls/DatetimeControl.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Alexander Shumilov 3 | * @copyright 2013-2023 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | import React from 'react'; 8 | import PropTypes from 'prop-types'; 9 | import dayjs from 'dayjs'; 10 | 11 | const FORMAT = `YYYY-MM-DD HH:mm:ss`; 12 | 13 | /** 14 | * Datetime control component 15 | */ 16 | class DatetimeControl extends React.Component { 17 | constructor(props) { 18 | super(props); 19 | dayjs.locale(navigator.language.indexOf(`da_`) === 0 ? "da" : "en"); 20 | } 21 | 22 | render() { 23 | return ( { this.props.onChange(event.target.value) }}/>); 30 | } 31 | } 32 | 33 | DatetimeControl.propTypes = { 34 | id: PropTypes.string.isRequired, 35 | value: PropTypes.string.isRequired, 36 | onChange: PropTypes.func.isRequired, 37 | }; 38 | 39 | export { DatetimeControl }; 40 | -------------------------------------------------------------------------------- /browser/modules/layerTree/controls/NumberControl.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Alexander Shumilov 3 | * @copyright 2013-2023 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | import React from 'react'; 8 | import PropTypes from 'prop-types'; 9 | import {SelectControl} from './SelectControl'; 10 | 11 | /** 12 | * Number control component 13 | */ 14 | class NumberControl extends React.Component { 15 | constructor(props) { 16 | super(props); 17 | } 18 | 19 | render() { 20 | if (this.props.restriction) { 21 | return (); 22 | } else { 23 | return ( { this.props.onChange(event.target.value) }}/>); 30 | } 31 | } 32 | } 33 | 34 | NumberControl.propTypes = { 35 | id: PropTypes.string.isRequired, 36 | value: PropTypes.string.isRequired, 37 | onChange: PropTypes.func.isRequired, 38 | }; 39 | 40 | export { NumberControl }; 41 | -------------------------------------------------------------------------------- /browser/modules/layerTree/controls/SelectControl.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Alexander Shumilov 3 | * @copyright 2013-2023 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | import React from 'react'; 8 | import PropTypes from 'prop-types'; 9 | 10 | /** 11 | * Select control component 12 | */ 13 | class SelectControl extends React.Component { 14 | constructor(props) { 15 | super(props); 16 | } 17 | 18 | render() { 19 | let options = []; 20 | options.push() 21 | this.props.restriction.map((option, index) => { 22 | options.push() 23 | }); 24 | 25 | return (); 28 | } 29 | } 30 | 31 | SelectControl.propTypes = { 32 | id: PropTypes.string.isRequired, 33 | value: PropTypes.string.isRequired, 34 | restriction: PropTypes.array.isRequired, 35 | onChange: PropTypes.func.isRequired, 36 | }; 37 | 38 | export { SelectControl }; 39 | -------------------------------------------------------------------------------- /browser/modules/layerTree/controls/StringControl.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Alexander Shumilov 3 | * @copyright 2013-2023 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | import React from 'react'; 8 | import PropTypes from 'prop-types'; 9 | import {SelectControl} from './SelectControl'; 10 | 11 | /** 12 | * String control component 13 | */ 14 | class StringControl extends React.Component { 15 | constructor(props) { 16 | super(props); 17 | } 18 | 19 | render() { 20 | if (this.props.restriction) { 21 | return (); 22 | } else { 23 | return ( { 30 | this.props.onChange(event.target.value) 31 | }}/>); 32 | } 33 | } 34 | } 35 | 36 | StringControl.propTypes = { 37 | id: PropTypes.string.isRequired, 38 | value: PropTypes.string.isRequired, 39 | onChange: PropTypes.func.isRequired, 40 | }; 41 | 42 | export { StringControl }; 43 | -------------------------------------------------------------------------------- /browser/modules/layerTree/controls/TimeControl.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Martin Høgh 3 | * @copyright 2013-2023 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | import React from 'react'; 8 | import PropTypes from 'prop-types'; 9 | import dayjs from 'dayjs'; 10 | 11 | const FORMAT = `YYYY-MM-DD`; 12 | 13 | /** 14 | * Time control component 15 | */ 16 | class TimeControl extends React.Component { 17 | constructor(props) { 18 | super(props); 19 | dayjs().locale(navigator.language.indexOf(`da_`) === 0 ? "da" : "en"); 20 | } 21 | 22 | render() { 23 | return ( { 30 | this.props.onChange(event.target.value) 31 | }}/>); 32 | } 33 | } 34 | 35 | TimeControl.propTypes = { 36 | id: PropTypes.string.isRequired, 37 | value: PropTypes.string.isRequired, 38 | onChange: PropTypes.func.isRequired, 39 | }; 40 | 41 | export {TimeControl}; 42 | -------------------------------------------------------------------------------- /browser/modules/layerTree/controls/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Alexander Shumilov 3 | * @copyright 2013-2023 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | import {StringControl} from './StringControl'; 8 | import {NumberControl} from './NumberControl'; 9 | import {BooleanControl} from './BooleanControl'; 10 | import {DateControl} from './DateControl'; 11 | import {DatetimeControl} from './DatetimeControl'; 12 | import {TimeControl} from './TimeControl'; 13 | import {AutocompleteControl} from './AutocompleteControl'; 14 | 15 | export {StringControl, NumberControl, BooleanControl, DateControl, DatetimeControl, TimeControl, AutocompleteControl}; 16 | -------------------------------------------------------------------------------- /browser/modules/layerTree/filterUtils.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Alexander Shumilov 3 | * @copyright 2013-2018 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | /** 8 | * Utilities for working woth layer filters 9 | */ 10 | 11 | const MATCHES = [`any`, `all`]; 12 | 13 | const EXPRESSIONS_FOR_STRINGS = [`=`, `<>`, `like`]; 14 | const EXPRESSIONS_FOR_NUMBERS = [`=`, `<>`, `<`, `>`, `<=`, `>=`]; 15 | const EXPRESSIONS_FOR_DATES = [`=`, `<>`, `<`, `>`, `<=`, `>=`]; 16 | const EXPRESSIONS_FOR_BOOLEANS = [`=`]; 17 | const EXPRESSIONS = [] 18 | .concat(EXPRESSIONS_FOR_NUMBERS) 19 | .concat(EXPRESSIONS_FOR_STRINGS) 20 | .concat(EXPRESSIONS_FOR_DATES) 21 | .concat(EXPRESSIONS_FOR_BOOLEANS) 22 | .filter((v, i, a) => a.indexOf(v) === i); 23 | 24 | /** 25 | * Checks validity of the filters object 26 | * 27 | * @throws {Error} 28 | */ 29 | const validateFilters = (filters) => { 30 | let errors = []; 31 | if (`match` in filters === false) errors.push(`Missing match property in filters`); 32 | if (MATCHES.indexOf(filters.match) === -1) errors.push(`Invalid match in filters`); 33 | 34 | if (`columns` in filters === false) errors.push(`Missing columns property in filters`); 35 | if (Array.isArray(filters.columns) === false) errors.push(`Invalid filter columns`); 36 | filters.columns.map(column => { 37 | if (`fieldname` in column === false) errors.push(`Column fieldname does not exist`); 38 | if (`expression` in column === false || (EXPRESSIONS.indexOf(column.expression) === -1 && column.expression !== `null`)) errors.push(`Invalid column expression`); 39 | if (`value` in column === false) errors.push(`Column value does not exist`); 40 | if (`sub` in column) errors = []; 41 | }); 42 | 43 | if (errors.length > 0) { 44 | console.error(`Invalid filters: ${errors.join(`,`)}`); 45 | throw new Error(`Invalid filters`); 46 | } 47 | }; 48 | 49 | export { validateFilters, MATCHES, EXPRESSIONS_FOR_STRINGS, EXPRESSIONS_FOR_NUMBERS, EXPRESSIONS_FOR_DATES, EXPRESSIONS_FOR_BOOLEANS, EXPRESSIONS }; 50 | -------------------------------------------------------------------------------- /browser/modules/pushState.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Martin Høgh 3 | * @copyright 2013-2018 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | 'use strict'; 8 | 9 | let anchor; 10 | let first = true; 11 | let t; 12 | const urlparser = require('./urlparser'); 13 | const urlVars = urlparser.urlVars; 14 | 15 | /** 16 | * 17 | * @type {{set: module.exports.set, init: module.exports.init}} 18 | */ 19 | module.exports = module.exports = { 20 | set: function (o) { 21 | anchor = o.anchor; 22 | return this; 23 | }, 24 | init: function () { 25 | // We don't set any state until 1 secs after the first request. This way CartoDB layers become ready. 26 | t = first ? 1000 : 0; 27 | setTimeout(function () { 28 | if (!urlVars.dps) { 29 | history.pushState(null, null, anchor.init()); 30 | } 31 | first = false; 32 | }, t); 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /browser/modules/reset.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Martin Høgh 3 | * @copyright 2013-2018 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | 'use strict'; 8 | 9 | let state, _self = false; 10 | 11 | /** 12 | * 13 | * @returns {*} 14 | */ 15 | module.exports = { 16 | 17 | /** 18 | * 19 | * @param o 20 | * @returns {exports} 21 | */ 22 | set: function (o) { 23 | state = o.state; 24 | _self = this; 25 | return this; 26 | }, 27 | 28 | /** 29 | * 30 | */ 31 | init: () => { 32 | $("#btn-reset").off(); 33 | $("#btn-reset").on("click", function () { 34 | _self.reset(); 35 | }); 36 | }, 37 | 38 | reset: () => { 39 | var curUrl = window.location.href, newUrl = curUrl.split("#")[0]; 40 | if (window.confirm(__(`Do you really want to reset the map?`))) { 41 | state.resetState().then(() => { 42 | // Do nothing 43 | }); 44 | } 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /browser/modules/shared/LoadingOverlay.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Alexander Shumilov 3 | * @copyright 2013-2023 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | const React = require('react'); 8 | 9 | /** 10 | * Loading overlay 11 | */ 12 | class LoadingOverlay extends React.Component { 13 | constructor(props) { 14 | super(props); 15 | } 16 | 17 | /** 18 | * Renders the component 19 | * 20 | * @returns {JSX.Element} 21 | */ 22 | render() { 23 | return (
28 |
29 |
{__(`Loading data`)}
30 |
31 |
32 |
33 |
34 |
); 35 | } 36 | } 37 | 38 | export default LoadingOverlay; 39 | -------------------------------------------------------------------------------- /browser/modules/socketId.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Martin Høgh 3 | * @copyright 2013-2018 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | 'use strict'; 8 | 9 | var socketId; 10 | 11 | /** 12 | * 13 | * @returns {*} 14 | */ 15 | module.exports = { 16 | 17 | /** 18 | * 19 | * @param o 20 | * @returns {exports} 21 | */ 22 | set: function (o) { 23 | return this; 24 | }, 25 | 26 | /** 27 | * 28 | */ 29 | init: function () { 30 | socketId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { 31 | var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); 32 | return v.toString(16); 33 | }); 34 | }, 35 | 36 | /** 37 | * 38 | * @returns string 39 | */ 40 | get: function () { 41 | return socketId; 42 | } 43 | 44 | }; -------------------------------------------------------------------------------- /browser/modules/stateSnapshots/components/TagComponent.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Martin Høgh 3 | * @copyright 2013-2024 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | import React, {StrictMode} from 'react'; 8 | import Multiselect from "react-widgets/Multiselect"; 9 | 10 | 11 | /** 12 | * Title field 13 | */ 14 | function TagComponent({onAdd, tags = [], allTags}) { 15 | 16 | function onAddTag(e) { 17 | const t = e; 18 | if (!t || t === '' || tags.includes(t)) { 19 | return 20 | } 21 | tags.push(t) 22 | onAdd(tags); 23 | } 24 | 25 | function onRemoveTag(e) { 26 | onAdd(e) 27 | } 28 | 29 | return (
30 | [__('Create tag'), searchTerm && ' ', searchTerm && React.createElement("strong", { 32 | key: "_" 33 | }, `"${searchTerm}"`)]}} 34 | data={tags ? allTags.filter((o) => tags?.indexOf(o) === -1).concat(tags.filter((o) => allTags.indexOf(o) === -1)) : allTags} 35 | value={tags} 36 | textField="fullName" 37 | allowCreate="onFilter" 38 | onCreate={onAddTag} 39 | onChange={onRemoveTag} 40 | /> 41 |
); 42 | } 43 | 44 | export default TagComponent; 45 | -------------------------------------------------------------------------------- /browser/modules/urlparser.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Martin Høgh 3 | * @copyright 2013-2020 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | 'use strict'; 8 | 9 | 10 | let url = new URL(window.location.href) 11 | let pathArray = url.pathname.split('/'); 12 | let searchParams = new URLSearchParams(url.search); 13 | let urlVars = {}; 14 | for (let p of searchParams) { 15 | urlVars[p[0]] = p[1]; 16 | } 17 | 18 | let _obj = { 19 | hostname: url.protocol + "//" + url.hostname + ":" + url.port, 20 | hash: decodeURIComponent(geocloud.urlHash), 21 | db: pathArray[2], 22 | schema: pathArray[3], 23 | staticRoute: pathArray[4], 24 | urlVars: urlVars, 25 | search: url.search, 26 | urlObj: url 27 | }; 28 | 29 | module.exports = _obj; 30 | -------------------------------------------------------------------------------- /browser/modules/utmZone.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Martin Høgh 3 | * @copyright 2013-2021 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | 'use strict'; 8 | 9 | 10 | /** 11 | * 12 | * @type {{set: module.exports.set, init: module.exports.init, getZone: module.exports.getZone}} 13 | */ 14 | module.exports = { 15 | set: function () { 16 | return this; 17 | }, 18 | init: function () { 19 | }, 20 | /** 21 | * Get the UTM zone from lat/lon 22 | * @param lat 23 | * @param lng 24 | * @returns {number} 25 | */ 26 | getZone: function (lat, lng) { 27 | // Get the UTM zone 28 | let zoneNumber = Math.floor((lng + 180) / 6) + 1; 29 | 30 | if (lat >= 56.0 && lat < 64.0 && lng >= 3.0 && lng < 12.0) { 31 | zoneNumber = 32; 32 | } 33 | //Special zones for Svalbard 34 | if (lat >= 72.0 && lat < 84.0) { 35 | if (lng >= 0.0 && lng < 9.0) { 36 | zoneNumber = 31; 37 | } 38 | else if (lng >= 9.0 && lng < 21.0) { 39 | zoneNumber = 33; 40 | } 41 | else if (lng >= 21.0 && lng < 33.0) { 42 | zoneNumber = 35; 43 | } 44 | else if (lng >= 33.0 && lng < 42.0) { 45 | zoneNumber = 37; 46 | } 47 | } 48 | return zoneNumber; 49 | } 50 | }; 51 | -------------------------------------------------------------------------------- /browser/service-worker/cache.production.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Alexander Shumilov 3 | * @copyright 2013-2018 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | /** 8 | * Production assets to cache 9 | */ 10 | 11 | let urlsToCache = [ 12 | '/index.html', 13 | 'https://netdna.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css', 14 | 'https://netdna.bootstrapcdn.com/font-awesome/4.5.0/fonts/fontawesome-webfont.woff2?v=4.5.0', 15 | '/fonts/roboto-v18-latin-italic.ttf', 16 | '/fonts/roboto-v18-latin-regular.ttf', 17 | '/fonts/roboto-v18-latin-500.ttf', 18 | '/fonts/roboto-v18-latin-italic.woff', 19 | '/fonts/roboto-v18-latin-regular.woff2', 20 | '/fonts/roboto-v18-latin-500.woff2', 21 | '/fonts/roboto-v18-latin-regular.woff', 22 | '/fonts/roboto-v18-latin-500.woff', 23 | '/fonts/roboto-v18-latin-italic.woff2', 24 | '/fonts/roboto-v18-latin-300.woff2', 25 | '/fonts/fa-regular-400.woff', 26 | '/fonts/fa-regular-400.woff2', 27 | '/fonts/fa-regular-400.ttf', 28 | '/fonts/fa-regular-400.svg', 29 | '/fonts/fa-solid-900.woff', 30 | '/fonts/fa-solid-900.woff2', 31 | '/fonts/fa-solid-900.ttf', 32 | '/fonts/fa-solid-900.svg', 33 | '/fonts/fonts.css', 34 | '/icons/MaterialIcons-Regular.woff2', 35 | '/icons/MaterialIcons-Regular.woff', 36 | '/icons/MaterialIcons-Regular.ttf', 37 | '/icons/material-icons.css', 38 | '/js/templates.js', 39 | '/locale', 40 | '/api/config/vidi.json' 41 | ]; 42 | 43 | module.exports = urlsToCache; 44 | -------------------------------------------------------------------------------- /controllers/config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Martin Høgh 3 | * @copyright 2013-2025 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | const express = require('express'); 8 | const router = express.Router(); 9 | const configUrl = require('../config/config.js').configUrl; 10 | const JsonRefs = require('json-refs'); 11 | 12 | router.get('/api/config/:db/:file', function (req, response) { 13 | let file = req.params.file, db = req.params.db, url; 14 | 15 | if (typeof configUrl === "object") { 16 | url = configUrl[db] || configUrl._default; 17 | } else { 18 | url = configUrl; 19 | } 20 | url = url + "/" + file; 21 | 22 | JsonRefs.clearCache() 23 | JsonRefs.resolveRefsAt(url, { 24 | loaderOptions: { 25 | prepareRequest: function (req2, callback) { 26 | callback(undefined, req2); 27 | } 28 | }, 29 | }).then(r => { 30 | response.send(r.resolved); 31 | }).catch(e => { 32 | response.header('content-type', 'application/json'); 33 | response.status(e.status).send({ 34 | success: false, 35 | message: "Could not get the requested config JSON file." 36 | }); 37 | }) 38 | }); 39 | module.exports = router; 40 | -------------------------------------------------------------------------------- /controllers/css.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Martin Høgh 3 | * @copyright 2013-2021 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | 8 | let express = require('express'); 9 | let router = express.Router(); 10 | let configUrl = require('../config/config.js').configUrl; 11 | let fetchUrl = require('fetch').fetchUrl; 12 | 13 | router.get('/api/css/:db/:folder?/:file', function (req, response) { 14 | let file = req.params.file, db = req.params.db, url; 15 | let folder = req.params?.folder; 16 | 17 | if (folder) { 18 | file = folder + "/" + file; 19 | } 20 | 21 | if (typeof configUrl === "object") { 22 | url = configUrl[db] || configUrl._default; 23 | } else { 24 | url = configUrl; 25 | } 26 | 27 | console.log("Getting css file", url + "/" + file); 28 | 29 | fetchUrl(url + "/" + file, function (err, meta, body) { 30 | if (err || meta.status !== 200) { 31 | response.header('content-type', 'application/json'); 32 | response.status(400).send({ 33 | success: false, 34 | message: "Could not get the requested css file." 35 | }); 36 | return; 37 | } 38 | response.header('content-type', 'text/css'); 39 | response.send(body.toString()); 40 | }); 41 | }); 42 | module.exports = router; 43 | -------------------------------------------------------------------------------- /controllers/df.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Martin Høgh 3 | * @copyright 2013-2021 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | const express = require('express'); 8 | const request = require('request'); 9 | const router = express.Router(); 10 | const config = require('../config/config.js'); 11 | 12 | router.get('/api/datafordeler/*', (req, response) => { 13 | const userName = config?.df?.datafordeler?.username; 14 | const pwd = config?.df?.datafordeler?.password; 15 | const token = config?.df?.datafordeler?.token; 16 | const host = 'https://services.datafordeler.dk'; 17 | let creds = token ? `&token=${token}` : `&username=${userName}&password=${pwd}`; 18 | let requestURL = host + decodeURIComponent(req.url.substr(17)) + creds; 19 | requestURL = requestURL.replace('false', 'FALSE'); 20 | get(requestURL, response); 21 | }); 22 | router.get('/api/dataforsyningen/*', (req, response) => { 23 | const userName = config?.df?.dataforsyningen?.username; 24 | const pwd = config?.df?.dataforsyningen?.password; 25 | const token = config?.df?.dataforsyningen?.token; 26 | const host = 'https://api.dataforsyningen.dk'; 27 | let creds = token ? `&token=${token}` : `&username=${userName}&password=${pwd}`; 28 | let requestURL = host + decodeURIComponent(req.url.substr(20)) + creds; 29 | requestURL = requestURL.replace('false', 'FALSE') 30 | 31 | // if the string has a parameter tileMatrixSet, with the value of View1 - we need to rewrite the tileMatrix value 32 | if (requestURL.includes('tileMatrixSet=View1')) { 33 | let tileMatrix = requestURL.match(/tileMatrix=\d+/); 34 | // pad the tileMatrix with 0 to 2 digits, and prefix the value with L 35 | let tileMatrixValue = tileMatrix[0].split('=')[1]; 36 | tileMatrixValue = 'L' + tileMatrixValue.padStart(2, '0').toString(); 37 | console.log(tileMatrixValue); 38 | // replace the tileMatrix value in the url with the new value 39 | requestURL = requestURL.replace(/tileMatrix=\d+/, 'tileMatrix='+tileMatrixValue); 40 | } 41 | 42 | get(requestURL, response); 43 | }); 44 | 45 | const get = (url, res) => { 46 | // Let the user decide if they want to redirect or wait for the response 47 | if (config?.df?.redirect) { 48 | res.redirect(url); 49 | 50 | // or wait for the response 51 | } else { 52 | let options = { 53 | method: 'GET', 54 | uri: url 55 | }; 56 | request(options).on('error', (e) => console.error(e)).pipe(res); 57 | } 58 | } 59 | module.exports = router; 60 | -------------------------------------------------------------------------------- /controllers/gc2/baseLayer.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Martin Høgh 3 | * @copyright 2013-2018 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | var express = require('express'); 8 | var router = express.Router(); 9 | var config = require('../../config/config.js').gc2; 10 | var request = require('request'); 11 | 12 | router.get('/api/baselayer', function (req, response) { 13 | var db = req.params.db, url; 14 | url = config.host + "/api/v1/baselayerjs/" + db; 15 | 16 | request.get(url, function (err, res, body) { 17 | console.log(url) 18 | 19 | if (err) { 20 | 21 | response.header('content-type', 'application/json'); 22 | response.status(400).send({ 23 | success: false, 24 | message: "Could not get the base layer data." 25 | }); 26 | 27 | return; 28 | } 29 | body+= ";window.gc2host='" + config.host + "';"; 30 | response.send((body)); 31 | }) 32 | }); 33 | module.exports = router; 34 | -------------------------------------------------------------------------------- /controllers/gc2/bulk.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Martin Høgh 3 | * @copyright 2013-2021 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | const express = require('express'); 8 | const router = express.Router(); 9 | const config = require('../../config/config.js').gc2; 10 | const request = require('request'); 11 | 12 | router.post('/api/bulk/:db', function (req, response) { 13 | let db = req.params.db, body = req.body, userName; 14 | 15 | // Check if user is a sub user 16 | if (req.session.screenName && req.session.subUser) { 17 | userName = req.session.screenName + "@" + db; 18 | } else { 19 | userName = db; 20 | } 21 | 22 | const uri = "/api/v2/sql/" + userName; 23 | 24 | const options = { 25 | method: 'POST', 26 | uri: config.host + uri, 27 | body: body, 28 | headers: { 29 | 'GC2-API-KEY': req.session.gc2ApiKey, 30 | 'Content-Type': 'text/plain' 31 | } 32 | }; 33 | 34 | request(options, function (err, res, body) { 35 | 36 | console.log(res.statusCode) 37 | 38 | if (err || res.statusCode !== 200) { 39 | 40 | response.header('content-type', 'application/json'); 41 | response.status(500).send({ 42 | success: false, 43 | message: body 44 | }); 45 | 46 | return; 47 | } 48 | 49 | response.header('content-type', 'application/json'); 50 | response.header('Cache-Control', 'no-cache, no-store, must-revalidate'); 51 | response.header('Expires', '0'); 52 | response.header('X-Powered-By', 'MapCentia Vidi'); 53 | 54 | response.send(body); 55 | }); 56 | }); 57 | module.exports = router 58 | -------------------------------------------------------------------------------- /controllers/gc2/config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Martin Høgh 3 | * @copyright 2013-2025 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | const express = require('express'); 8 | const router = express.Router(); 9 | const config = require('../../config/config.js').gc2; 10 | const request = require('request'); 11 | const JsonRefs = require('json-refs'); 12 | 13 | router.get('/api/gc2/config/:db/:id?', function (req, response) { 14 | let url; 15 | const db = req.params.db; 16 | const id = req.params.id?.replace('.json', ''); 17 | 18 | url = config.host + "/api/v2/configuration/" + db + (id ? "/" + id : ""); 19 | 20 | let headers = { 21 | Cookie: "PHPSESSID=" + req?.session?.gc2SessionId 22 | } 23 | let options = { 24 | uri: url, 25 | encoding: 'utf8', 26 | headers 27 | }; 28 | 29 | request.get(options, function (err, res, body) { 30 | if (res.statusCode !== 200) { 31 | response.header('content-type', 'application/json'); 32 | response.status(403).send({ 33 | success: false, 34 | message: "Could not get the requested config JSON file." 35 | }); 36 | return; 37 | } 38 | const data = JSON.parse(body); 39 | const parsedData = id ? JSON.parse(JSON.parse(data.data.value).body) : data; 40 | JsonRefs.clearCache() 41 | JsonRefs.resolveRefs(parsedData).then(r => { 42 | response.send(r.resolved); 43 | }).catch(e => { 44 | response.header('content-type', 'application/json'); 45 | response.status(e.status).send({ 46 | success: false, 47 | message: "Could not get the requested config JSON file." 48 | }); 49 | }) 50 | }) 51 | }); 52 | module.exports = router; 53 | -------------------------------------------------------------------------------- /controllers/gc2/elasticsearch.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Martin Høgh 3 | * @copyright 2013-2020 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | let express = require('express'); 8 | let router = express.Router(); 9 | let config = require('../../config/config.js').gc2; 10 | let request = require('request'); 11 | 12 | router.post('/api/elasticsearch/search/:db/:schema/:relation', function (req, response) { 13 | let schema = req.params.schema; 14 | let db = req.params.db; 15 | let relation = req.params.relation; 16 | let body = req.body 17 | let url = config.host + `/api/v2/elasticsearch/search/${db}/${schema}/${relation}`; 18 | let options = { 19 | method: 'POST', 20 | uri: url, 21 | json: body, 22 | headers: {} 23 | }; 24 | request.post(options, function (err, res, body) { 25 | if (err || res.statusCode !== 200) { 26 | response.header('content-type', 'application/json'); 27 | response.status(400).send({ 28 | success: false, 29 | message: "Could not get data." 30 | }); 31 | return; 32 | } 33 | response.send(body); 34 | }) 35 | }); 36 | module.exports = router; 37 | -------------------------------------------------------------------------------- /controllers/gc2/feature.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Martin Høgh 3 | * @copyright 2013-2022 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | const express = require('express'); 8 | const router = express.Router(); 9 | const config = require('../../config/config.js').gc2; 10 | const request = require('request'); 11 | 12 | router.all('/api/feature/:db/:layer/:param', function (req, response) { 13 | const db = req.params.db, layer = req.params.layer, param = req.params.param, body = req.body; 14 | let userName; 15 | 16 | // Check if user is a sub user 17 | if (req?.session?.screenName && req.session?.subUser) { 18 | userName = req?.session?.screenName + "@" + db; 19 | } else { 20 | userName = db; 21 | } 22 | const uri = "/api/v2/feature/" + userName + "/" + layer + "/4326/" + param; 23 | const options = { 24 | method: req.method, 25 | uri: config.host + uri, 26 | json: body, 27 | headers: { 28 | 'Cookie': "XDEBUG_SESSION=XDEBUG_SESSION;PHPSESSID=" + req?.session?.gc2SessionId, 29 | 'GC2-API-KEY': req?.session?.gc2ApiKey 30 | } 31 | }; 32 | request(options, function (err, res, body) { 33 | if (err || res.statusCode !== 200) { 34 | response.header('content-type', 'application/json'); 35 | response.status(500).send({ 36 | success: false, 37 | message: body 38 | }); 39 | return; 40 | } 41 | response.header('content-type', 'application/json'); 42 | response.header('Cache-Control', 'no-cache, no-store, must-revalidate'); 43 | response.header('Expires', '0'); 44 | response.header('X-Powered-By', 'MapCentia Vidi'); 45 | response.send(body); 46 | }); 47 | }); 48 | module.exports = router; 49 | -------------------------------------------------------------------------------- /controllers/gc2/legend.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Martin Høgh 3 | * @copyright 2013-2018 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | var express = require('express'); 8 | var router = express.Router(); 9 | var config = require('../../config/config.js').gc2; 10 | var request = require('request'); 11 | 12 | router.get('/api/legend/:db', function (req, response) { 13 | 14 | var l = req.query.l, db = req.params.db, url; 15 | 16 | url = config.host + "/api/v1/legend/json/" + db + "?l=" + encodeURIComponent(l); 17 | 18 | var options = { 19 | uri: url, 20 | encoding: 'utf8', 21 | headers: { 22 | Cookie: "PHPSESSID=" + req?.session?.gc2SessionId 23 | } 24 | }; 25 | 26 | request.get(options, 27 | function (err, res, body) { 28 | if (err) console.error(err); 29 | if (res.statusCode !== 200) { 30 | response.header('content-type', 'application/json'); 31 | response.status(400).send({ 32 | success: false, 33 | message: "Could not get the legend data." 34 | }); 35 | return; 36 | } 37 | response.send(JSON.parse(body)); 38 | } 39 | ) 40 | }); 41 | module.exports = router; -------------------------------------------------------------------------------- /controllers/gc2/meta.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Martin Høgh 3 | * @copyright 2013-2022 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | const express = require('express'); 8 | const router = express.Router(); 9 | const config = require('../../config/config.js'); 10 | const request = require('request'); 11 | const utf8 = require('utf8'); 12 | let app = express(); 13 | 14 | router.get('/api/meta/:db/:schema', function (req, response) { 15 | const db = req.params.db 16 | const schema = req.params.schema; 17 | const addedSchemata = typeof config.addedSchemata !== "undefined" ? "," + config.addedSchemata : ""; 18 | let url, options; 19 | let headers = { 20 | Cookie: "PHPSESSID=" + req?.session?.gc2SessionId 21 | } 22 | if (app.get('env') === 'test') { 23 | headers.Cookie += "; XDEBUG_SESSION=XDEBUG_SESSION;"; 24 | } 25 | url = config.gc2.host + "/api/v1/meta/" + db + "/" + utf8.encode(schema) + addedSchemata; 26 | options = { 27 | uri: url, 28 | encoding: 'utf8', 29 | headers 30 | }; 31 | request.get(options, 32 | function (err, res, body) { 33 | if (err) { 34 | response.header('content-type', 'application/json'); 35 | response.status(400).send({ 36 | success: false, 37 | message: "Could not get the meta data." 38 | }); 39 | 40 | return; 41 | } 42 | response.send(JSON.parse(body)); 43 | }) 44 | }); 45 | module.exports = router; 46 | 47 | -------------------------------------------------------------------------------- /controllers/gc2/setting.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Martin Høgh 3 | * @copyright 2013-2018 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | var express = require('express'); 8 | var router = express.Router(); 9 | var http = require('http'); 10 | var config = require('../../config/config.js').gc2; 11 | var request = require('request'); 12 | 13 | router.get('/api/setting/:db/:schema', function (req, response) { 14 | var db = req.params.db, url; 15 | url = config.host + "/api/v1/setting/" + db; 16 | 17 | request.get(url, function (err, res, body) { 18 | 19 | if (err) { 20 | 21 | response.header('content-type', 'application/json'); 22 | response.status(400).send({ 23 | success: false, 24 | message: "Could not get the settings data." 25 | }); 26 | 27 | return; 28 | } 29 | 30 | response.send(JSON.parse(body)); 31 | }) 32 | }); 33 | module.exports = router; 34 | -------------------------------------------------------------------------------- /controllers/gc2/shared.js: -------------------------------------------------------------------------------- 1 | const TRACKER_COOKIE_NAME = `vidi-state-tracker`; 2 | 3 | const throwError = (response, error, data) => { 4 | console.error(`Error occured: ${error}`); 5 | if (data) console.error(`Error details: ${JSON.stringify(data)}`); 6 | 7 | response.status(400); 8 | response.json({error}); 9 | }; 10 | 11 | /** 12 | * Return identifiers of the currently authenticated user 13 | * 14 | * @returns {Object} 15 | */ 16 | const getCurrentUserIdentifiers = (request) => { 17 | let browserId = false; 18 | if (TRACKER_COOKIE_NAME in request.cookies) { 19 | browserId = request.cookies[TRACKER_COOKIE_NAME]; 20 | } 21 | 22 | let userId = false; 23 | if (request?.session?.gc2UserName) { 24 | userId = request.session.gc2UserName; 25 | } 26 | 27 | return {browserId, userId}; 28 | }; 29 | 30 | module.exports = { 31 | throwError, 32 | getCurrentUserIdentifiers 33 | } 34 | -------------------------------------------------------------------------------- /controllers/gc2/wms.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Martin Høgh 3 | * @copyright 2013-2022 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | const express = require('express'); 8 | const router = express.Router(); 9 | const config = require('../../config/config.js').gc2; 10 | const request = require('request'); 11 | 12 | const proxifyRequest = (req, response) => { 13 | let requestURL = config.host + encodeURI(decodeURIComponent(req.url.substr(4))); 14 | 15 | // Rewrite URL in case of subUser 16 | if (req?.session?.subUser && !req.url.includes('/mapcache/')) { 17 | requestURL = requestURL.replace(`/${req.session.parentDb}/`, `/${req.session.screenName}@${req.session.parentDb}/`); 18 | } 19 | 20 | let options = { 21 | method: 'GET', 22 | uri: requestURL 23 | }; 24 | 25 | if (req?.session?.gc2SessionId) { 26 | options.headers = {Cookie: "PHPSESSID=" + req.session.gc2SessionId + ";"} 27 | } 28 | 29 | request(options).pipe(response); 30 | }; 31 | 32 | router.all('/api/wms/:db/:schema', proxifyRequest); 33 | router.all('/api/mapcache/:db/wms', proxifyRequest); 34 | router.all('/api/mapcache/:db/gmaps/*', proxifyRequest); 35 | 36 | module.exports = router; 37 | -------------------------------------------------------------------------------- /controllers/headlessBrowserPool.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Martin Høgh 3 | * @copyright 2013-2019 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | const genericPool = require("generic-pool"); 8 | 9 | const puppeteer = require('puppeteer'); 10 | 11 | const config = require('../config/config.js') 12 | 13 | let puppeteerProcesses = {}; 14 | 15 | if (typeof config.puppeteerProcesses !== "undefined") { 16 | puppeteerProcesses.min = typeof config.puppeteerProcesses.min !== "undefined" ? config.puppeteerProcesses.min : 0; 17 | puppeteerProcesses.max = typeof config.puppeteerProcesses.max !== "undefined" ? config.puppeteerProcesses.max : 2; 18 | } else { 19 | puppeteerProcesses = {min: 0, max: 2}; 20 | } 21 | 22 | const startupParameters = { 23 | headless: true, 24 | timeout: 10000, 25 | ignoreHTTPSErrors: true, 26 | args: [ 27 | "--no-sandbox", 28 | "--disable-setuid-sandbox", 29 | "--enable-features=NetworkService", 30 | // '--use-gl=angle', 31 | // '--enable-webgl', 32 | // '--ignore-gpu-blocklist', 33 | // '--use-gl=egl', 34 | // '--enable-accelerated-2d-canvas', 35 | // '--disable-software-rasterizer', 36 | // '--disable-gpu-sandbox', 37 | // '--enable-webgl-draft-extensions', 38 | // '--enable-es3-apis', 39 | ], 40 | //userDataDir: '/tmp/chromeSession' 41 | }; 42 | 43 | const pool = genericPool.createPool({ 44 | create() { 45 | return puppeteer.launch(startupParameters); 46 | }, 47 | destroy(browser) { 48 | return browser.close(); 49 | }, 50 | validate(browser) { 51 | return Promise.race([ 52 | new Promise(res => setTimeout(() => res(false), 1500)), 53 | browser.version().then(_ => true).catch(_ => false) 54 | ]) 55 | }, 56 | }, { 57 | min: puppeteerProcesses.min, 58 | max: puppeteerProcesses.max, 59 | testOnBorrow: true, 60 | acquireTimeoutMillis: 500, // Should be bigger that it takes to start a headless browser 61 | evictionRunIntervalMillis: 5000, 62 | numTestsPerEvictionRun: 3, // Default 63 | maxWaitingClients: 5, 64 | idleTimeoutMillis: 30000 65 | 66 | }) 67 | 68 | setInterval(() => { 69 | if (pool.size === pool.max) { 70 | let poolInfo = { 71 | "pool.max": pool.max, 72 | "pool.size": pool.size, 73 | "pool.available": pool.available, 74 | "pool.borrowed": pool.borrowed, 75 | "pool.pending": pool.pending, 76 | "pool.spareResourceCapacity": pool.spareResourceCapacity 77 | } 78 | console.log(poolInfo) 79 | } 80 | }, 5000) 81 | 82 | module.exports = {pool}; 83 | -------------------------------------------------------------------------------- /controllers/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Martin Høgh 3 | * @copyright 2013-2021 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | const express = require('express'); 8 | const router = express.Router(); 9 | 10 | router.use(require('./gc2/meta')); 11 | router.use(require('./gc2/stateSnapshots')); 12 | router.use(require('./gc2/setting')); 13 | router.use(require('./gc2/baseLayer')); 14 | router.use(require('./gc2/wms')); 15 | router.use(require('./gc2/keyValue')); 16 | router.use(require('./gc2/legend')); 17 | router.use(require('./gc2/sql')); 18 | router.use(require('./gc2/elasticsearch')); 19 | router.use(require('./gc2/feature')); 20 | router.use(require('./gc2/bulk')); 21 | router.use(require('./gc2/config')); 22 | router.use(require('./print')); 23 | router.use(require('./locale')); 24 | router.use(require('./config')); 25 | router.use(require('./static')); 26 | router.use(require('./template')); 27 | router.use(require('./css')); 28 | router.use(require('./mergePrint')); 29 | router.use(require('./df')); 30 | 31 | module.exports = router; 32 | -------------------------------------------------------------------------------- /controllers/locale.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Martin Høgh 3 | * @copyright 2013-2025 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | const express = require('express'); 8 | const router = express.Router(); 9 | const ipaddr = require('ipaddr.js'); 10 | 11 | router.get('/locale', function(request, response) { 12 | const ip = ipaddr.process(request.ip).toString(); 13 | let decimalSeparator; 14 | let lang = request.acceptsLanguages('en', 'en-US', 'da', 'da-DK'); 15 | decimalSeparator = "." 16 | if (lang) { 17 | if (lang === "en") { 18 | lang = "en-US"; 19 | } 20 | if (lang === "da") { 21 | lang = "da-DK"; 22 | decimalSeparator = "," 23 | } 24 | } else { 25 | lang = "en-US"; 26 | } 27 | lang = lang.replace("-","_"); 28 | response.set('Content-Type', 'application/javascript'); 29 | response.send("window.decimalSeparator='" + decimalSeparator + "'; window._vidiIp = '" + ip + "'; var urlVars = (function getUrlVars() {var mapvars = {};var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function (m, key, value) {mapvars[key] = value;});return mapvars;})(); if (urlVars.locale !== undefined){window._vidiLocale=urlVars.locale.split('#')[0]} else {window._vidiLocale='" + lang + "'}"); 30 | }); 31 | module.exports = router; 32 | -------------------------------------------------------------------------------- /controllers/mergePrint.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Martin Høgh 3 | * @copyright 2013-2020 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | require('dotenv').config(); 7 | 8 | let express = require('express'); 9 | let router = express.Router(); 10 | const PDFMerge = require('pdf-merge'); 11 | 12 | 13 | /** 14 | * 15 | * @type {module.exports.print|{templates, scales}} 16 | */ 17 | router.post('/api/mergePrint', function (req, response) { 18 | req.setTimeout(0); // no timeout 19 | let files = req.body.map((key)=> `${__dirname}/../public/tmp/print/pdf/${key}.pdf`); 20 | let key = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { 21 | let r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); 22 | return v.toString(16); 23 | }); 24 | PDFMerge(files, {output: `${__dirname}/../public/tmp/print/pdf/${key}.pdf`}) 25 | .then((buffer) => { 26 | response.send({success: true, key}); 27 | }); 28 | } 29 | ); 30 | 31 | module.exports = router; 32 | -------------------------------------------------------------------------------- /controllers/template.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Martin Høgh 3 | * @copyright 2013-2021 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | let express = require('express'); 8 | let router = express.Router(); 9 | let configUrl = require('../config/config.js').configUrl; 10 | let fetchUrl = require('fetch').fetchUrl; 11 | 12 | router.get('/api/template/:db/:folder?/:file', function (req, response) { 13 | let file = req.params.file, db = req.params.db, url, rem; 14 | let folder = req.params?.folder; 15 | 16 | if (folder) { 17 | file = folder + "/" + file; 18 | } 19 | 20 | if (typeof configUrl === "object") { 21 | url = configUrl[db] || configUrl._default; 22 | } else { 23 | url = configUrl; 24 | } 25 | 26 | console.log(url + "/" + file); 27 | 28 | fetchUrl(url + "/" + file, function (err, meta, body) { 29 | if (err || meta.status !== 200) { 30 | response.header('content-type', 'application/json'); 31 | response.status(400).send({ 32 | success: false, 33 | message: "Could not get the requested template file." 34 | }); 35 | return; 36 | } 37 | response.header('content-type', 'text/plain'); 38 | response.send(body.toString()); 39 | }); 40 | }); 41 | module.exports = router; 42 | -------------------------------------------------------------------------------- /docker/base/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:bookworm-slim 2 | 3 | MAINTAINER Martin Høgh 4 | 5 | RUN export DEBIAN_FRONTEND=noninteractive 6 | ENV DEBIAN_FRONTEND noninteractive 7 | 8 | # Install packages 9 | RUN apt-get -y update --allow-releaseinfo-change 10 | RUN apt-get -y install wget curl vim git supervisor postgresql-client default-jre gnupg2 locales libssl-dev libxss-dev pdftk bzip2 chromium ruby-full rubygems 11 | 12 | RUN curl -sL https://deb.nodesource.com/setup_20.x -o nodesource_setup.sh &&\ 13 | bash nodesource_setup.sh &&\ 14 | apt-get install -y nodejs 15 | 16 | RUN npm install -g sass grunt-cli 17 | 18 | HEALTHCHECK --interval=30s --timeout=20s --start-period=30s --retries=2 \ 19 | CMD curl --fail http://127.0.0.1:3000 || exit 1 20 | 21 | # Add Supervisor config and run the deamon 22 | ADD conf/supervisor/supervisord.conf /etc/supervisor/conf.d/supervisord.conf 23 | CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"] 24 | -------------------------------------------------------------------------------- /docker/base/conf/supervisor/supervisord.conf: -------------------------------------------------------------------------------- 1 | [supervisord] 2 | nodaemon=true 3 | 4 | [supervisorctl] 5 | serverurl=http://localhost:9001 6 | 7 | [rpcinterface:supervisor] 8 | supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface 9 | 10 | [inet_http_server] 11 | port=127.0.0.1:9001 12 | 13 | [program:vidi] 14 | command=/bin/bash -c "node ~/vidi -D FOREGROUND" 15 | priority=1 16 | stdout_logfile=/dev/stdout 17 | stdout_logfile_maxbytes=0 18 | stderr_logfile=/dev/stderr 19 | stderr_logfile_maxbytes=0 20 | -------------------------------------------------------------------------------- /docker/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | 3 | services: 4 | base: 5 | build: ./base 6 | image: mapcentia/vidi:base18 7 | vidi: 8 | build: ./stable 9 | image: mapcentia/vidi 10 | depends_on: 11 | - base 12 | -------------------------------------------------------------------------------- /docker/stable/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mapcentia/vidi:base18 2 | MAINTAINER Martin Høgh 3 | 4 | RUN export DEBIAN_FRONTEND=noninteractive 5 | ENV DEBIAN_FRONTEND noninteractive 6 | 7 | # Clone Vidi from GitHub 8 | RUN cd ~ &&\ 9 | git clone https://github.com/mapcentia/vidi.git 10 | 11 | # Install grunt 12 | RUN cd ~/vidi &&\ 13 | npm install grunt-cli -g --save-dev 14 | 15 | # Install packages 16 | RUN cd ~/vidi &&\ 17 | npm install 18 | 19 | #Add config files from Git repo 20 | COPY conf/vidi/config.js /root/vidi/config/config.js 21 | 22 | #Run Grunt 23 | RUN cd ~/vidi &&\ 24 | grunt production 25 | 26 | EXPOSE 3000 27 | 28 | # Share the source dir 29 | VOLUME ["/root/vidi"] 30 | -------------------------------------------------------------------------------- /docs/_media/baselayer-drawer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/docs/_media/baselayer-drawer.png -------------------------------------------------------------------------------- /docs/_media/cross-multi-select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/docs/_media/cross-multi-select.png -------------------------------------------------------------------------------- /docs/_media/draw-create-line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/docs/_media/draw-create-line.png -------------------------------------------------------------------------------- /docs/_media/draw-create-polygon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/docs/_media/draw-create-polygon.png -------------------------------------------------------------------------------- /docs/_media/draw-edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/docs/_media/draw-edit.png -------------------------------------------------------------------------------- /docs/_media/draw-linestyle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/docs/_media/draw-linestyle.png -------------------------------------------------------------------------------- /docs/_media/draw-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/docs/_media/draw-list.png -------------------------------------------------------------------------------- /docs/_media/draw-on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/docs/_media/draw-on.png -------------------------------------------------------------------------------- /docs/_media/extensions-directions-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/docs/_media/extensions-directions-icon.png -------------------------------------------------------------------------------- /docs/_media/feature-info-table-on-map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/docs/_media/feature-info-table-on-map.png -------------------------------------------------------------------------------- /docs/_media/filter-autocomplete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/docs/_media/filter-autocomplete.png -------------------------------------------------------------------------------- /docs/_media/gc2-meta-editor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/docs/_media/gc2-meta-editor.png -------------------------------------------------------------------------------- /docs/_media/gc2-meta-filters.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/docs/_media/gc2-meta-filters.png -------------------------------------------------------------------------------- /docs/_media/gc2-meta-filters2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/docs/_media/gc2-meta-filters2.png -------------------------------------------------------------------------------- /docs/_media/gc2-meta-references.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/docs/_media/gc2-meta-references.png -------------------------------------------------------------------------------- /docs/_media/gc2-meta.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/docs/_media/gc2-meta.png -------------------------------------------------------------------------------- /docs/_media/gettingstarted-controls.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/docs/_media/gettingstarted-controls.png -------------------------------------------------------------------------------- /docs/_media/gettingstarted-main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/docs/_media/gettingstarted-main.png -------------------------------------------------------------------------------- /docs/_media/gettingstarted-menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/docs/_media/gettingstarted-menu.png -------------------------------------------------------------------------------- /docs/_media/json-refs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/docs/_media/json-refs.png -------------------------------------------------------------------------------- /docs/_media/layer-search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/docs/_media/layer-search.png -------------------------------------------------------------------------------- /docs/_media/measure-create-area.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/docs/_media/measure-create-area.png -------------------------------------------------------------------------------- /docs/_media/measure-create-line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/docs/_media/measure-create-line.png -------------------------------------------------------------------------------- /docs/_media/measure-edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/docs/_media/measure-edit.png -------------------------------------------------------------------------------- /docs/_media/measure-on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/docs/_media/measure-on.png -------------------------------------------------------------------------------- /docs/_media/meow.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/docs/_media/meow.jpg -------------------------------------------------------------------------------- /docs/_media/print-complete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/docs/_media/print-complete.png -------------------------------------------------------------------------------- /docs/_media/print-on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/docs/_media/print-on.png -------------------------------------------------------------------------------- /docs/_media/print-ready.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/docs/_media/print-ready.png -------------------------------------------------------------------------------- /docs/_media/project-on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/docs/_media/project-on.png -------------------------------------------------------------------------------- /docs/_media/responsive-sidebar-collapsed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/docs/_media/responsive-sidebar-collapsed.png -------------------------------------------------------------------------------- /docs/_media/responsive-sidebar-expanded.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/docs/_media/responsive-sidebar-expanded.png -------------------------------------------------------------------------------- /docs/_media/sidebar-collapsed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/docs/_media/sidebar-collapsed.png -------------------------------------------------------------------------------- /docs/_media/sidebar-expanded.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/docs/_media/sidebar-expanded.png -------------------------------------------------------------------------------- /docs/_media/structur-tab-properties.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/docs/_media/structur-tab-properties.png -------------------------------------------------------------------------------- /docs/_media/structure-overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/docs/_media/structure-overview.png -------------------------------------------------------------------------------- /docs/_media/vector-table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/docs/_media/vector-table.png -------------------------------------------------------------------------------- /docs/_media/vidi-responsive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/docs/_media/vidi-responsive.png -------------------------------------------------------------------------------- /docs/_subs/CHANGELOG.rst: -------------------------------------------------------------------------------- 1 | .. _CHANGELOG: 2 | 3 | 4 | Changelog 5 | ================================================================= 6 | 7 | .. mdinclude:: ../../CHANGELOG.md -------------------------------------------------------------------------------- /docs/_subs/CONTRIBUTING.rst: -------------------------------------------------------------------------------- 1 | .. _CONTRIBUTING: 2 | 3 | 4 | Contributing 5 | ================================================================= 6 | 7 | .. mdinclude:: ../../CONTRIBUTING.md -------------------------------------------------------------------------------- /docs/_subs/GIT.rst: -------------------------------------------------------------------------------- 1 | .. _GIT: 2 | 3 | Mere om Vidi-projektet 4 | """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 5 | 6 | Her er links til mere generel information 7 | 8 | * :ref:`README` 9 | * :ref:`CHANGELOG` 10 | * :ref:`CONTRIBUTING` -------------------------------------------------------------------------------- /docs/_subs/NOTE_CONF.rst: -------------------------------------------------------------------------------- 1 | .. _NOTE_CONFIG: 2 | 3 | .. note:: 4 | Indhold i dette værktøj er betinget af opsætningen af Vidi. 5 | 6 | For at læse mere om opsætningen, kan du gå til :ref:`configjs` eller :ref:`configjson` 7 | 8 | -------------------------------------------------------------------------------- /docs/_subs/NOTE_GETTINGSTARTED.rst: -------------------------------------------------------------------------------- 1 | .. _NOTE_GETTINGSTARTED: 2 | 3 | .. note:: 4 | Hvis du er i tvivl om de forskellige UI-elementer, :ref:`kan du se mere her ` 5 | -------------------------------------------------------------------------------- /docs/_subs/README.rst: -------------------------------------------------------------------------------- 1 | .. _README: 2 | 3 | 4 | Readme 5 | ================================================================= 6 | 7 | .. mdinclude:: ../../README.md -------------------------------------------------------------------------------- /docs/_subs/WARNING_OLD_DOC.rst: -------------------------------------------------------------------------------- 1 | .. _OLDWARNING: 2 | 3 | .. warning:: Indhold fra denne side er overført direkte fra ældre wiki, og kan derfor være uddateret. Billeder er linket udenfor dette bibliotek. 4 | 5 | Du er velkommen til at hjælpe med at holde dokumentationen opdateret. Læs mere her 6 | 7 | :ref:`CONTRIBUTING` -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | ################################################################# 2 | Vidi brugerdokumentation 3 | ################################################################# 4 | 5 | Hvis du har brug for at komme i gang med Vidi fra bunden af, er her et godt sted at starte. 6 | 7 | .. toctree:: 8 | :maxdepth: 1 9 | :glob: 10 | 11 | pages/gettingstarted/* 12 | 13 | ***************************************************************** 14 | Standardværktøjer 15 | ***************************************************************** 16 | 17 | Vidi indeholder en del værktøjer som altid er slået til. Disse værktøjer er lavet til at at gøre arbejdet nemmere. Du kan læse mere om de enkelse værktøjer herunder. 18 | 19 | .. toctree:: 20 | :maxdepth: 1 21 | :glob: 22 | 23 | pages/standard/* 24 | 25 | ***************************************************************** 26 | Extensions 27 | ***************************************************************** 28 | 29 | Ud over standardværktøjerne, er der udviddet funktionalitet som du kan læse mere om herunder. 30 | 31 | .. toctree:: 32 | :maxdepth: 1 33 | :glob: 34 | 35 | pages/extensions/* 36 | 37 | 38 | .. Include generic links to repo 39 | 40 | .. include:: ./_subs/GIT.rst 41 | -------------------------------------------------------------------------------- /docs/locales/en/LC_MESSAGES/_subs/GIT.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) 2023, MapCentia 3 | # This file is distributed under the same license as the Vidi package. 4 | # FIRST AUTHOR , 2024. 5 | # 6 | #, fuzzy 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: Vidi 1.0\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "POT-Creation-Date: 2024-01-09 12:34+0100\n" 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 13 | "Last-Translator: FULL NAME \n" 14 | "Language: en\n" 15 | "Language-Team: en \n" 16 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 17 | "MIME-Version: 1.0\n" 18 | "Content-Type: text/plain; charset=utf-8\n" 19 | "Content-Transfer-Encoding: 8bit\n" 20 | "Generated-By: Babel 2.12.1\n" 21 | 22 | #: ../../_subs/GIT.rst:4 44b6576abce94e2eb810f3a9baaaad1c 23 | msgid "Mere om Vidi-projektet" 24 | msgstr "" 25 | 26 | #: ../../_subs/GIT.rst:6 b0791ce21daa4fc8a7afe289514b23ef 27 | msgid "Her er links til mere generel information" 28 | msgstr "" 29 | 30 | #: ../../_subs/GIT.rst:8 a7455dbb497f49eb8839c2f785ebdbe6 31 | msgid ":ref:`README`" 32 | msgstr "" 33 | 34 | #: ../../_subs/GIT.rst:9 4e5b029ac98b44128719e0d8063a14ee 35 | msgid ":ref:`CHANGELOG`" 36 | msgstr "" 37 | 38 | #: ../../_subs/GIT.rst:10 f7f8f1cf1d184b67bf43048b02b37fde 39 | msgid ":ref:`CONTRIBUTING`" 40 | msgstr "" 41 | 42 | -------------------------------------------------------------------------------- /docs/locales/en/LC_MESSAGES/_subs/NOTE_CONF.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) 2023, MapCentia 3 | # This file is distributed under the same license as the Vidi package. 4 | # FIRST AUTHOR , 2024. 5 | # 6 | #, fuzzy 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: Vidi 1.0\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "POT-Creation-Date: 2024-01-09 12:34+0100\n" 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 13 | "Last-Translator: FULL NAME \n" 14 | "Language: en\n" 15 | "Language-Team: en \n" 16 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 17 | "MIME-Version: 1.0\n" 18 | "Content-Type: text/plain; charset=utf-8\n" 19 | "Content-Transfer-Encoding: 8bit\n" 20 | "Generated-By: Babel 2.12.1\n" 21 | 22 | #: ../../_subs/NOTE_CONF.rst:4 2ee52ac9ddce49108b1b5c6ad969d6bb 23 | msgid "Indhold i dette værktøj er betinget af opsætningen af Vidi." 24 | msgstr "" 25 | 26 | #: ../../_subs/NOTE_CONF.rst:6 a67282e9790d43aba4d3677730475586 27 | msgid "" 28 | "For at læse mere om opsætningen, kan du gå til :ref:`configjs` eller " 29 | ":ref:`configjson`" 30 | msgstr "" 31 | 32 | -------------------------------------------------------------------------------- /docs/locales/en/LC_MESSAGES/_subs/NOTE_GETTINGSTARTED.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) 2023, MapCentia 3 | # This file is distributed under the same license as the Vidi package. 4 | # FIRST AUTHOR , 2024. 5 | # 6 | #, fuzzy 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: Vidi 1.0\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "POT-Creation-Date: 2024-01-09 12:34+0100\n" 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 13 | "Last-Translator: FULL NAME \n" 14 | "Language: en\n" 15 | "Language-Team: en \n" 16 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 17 | "MIME-Version: 1.0\n" 18 | "Content-Type: text/plain; charset=utf-8\n" 19 | "Content-Transfer-Encoding: 8bit\n" 20 | "Generated-By: Babel 2.12.1\n" 21 | 22 | #: ../../_subs/NOTE_GETTINGSTARTED.rst:4 235a9fca0ebe44ffa5c487cfd7cef0e8 23 | msgid "" 24 | "Hvis du er i tvivl om de forskellige UI-elementer, :ref:`kan du se mere " 25 | "her `" 26 | msgstr "" 27 | 28 | -------------------------------------------------------------------------------- /docs/locales/en/LC_MESSAGES/_subs/WARNING_OLD_DOC.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) 2023, MapCentia 3 | # This file is distributed under the same license as the Vidi package. 4 | # FIRST AUTHOR , 2024. 5 | # 6 | #, fuzzy 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: Vidi 1.0\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "POT-Creation-Date: 2024-01-09 12:34+0100\n" 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 13 | "Last-Translator: FULL NAME \n" 14 | "Language: en\n" 15 | "Language-Team: en \n" 16 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 17 | "MIME-Version: 1.0\n" 18 | "Content-Type: text/plain; charset=utf-8\n" 19 | "Content-Transfer-Encoding: 8bit\n" 20 | "Generated-By: Babel 2.12.1\n" 21 | 22 | #: ../../_subs/WARNING_OLD_DOC.rst:3 9de3a679ba4845908b3e264c583210c5 23 | msgid "" 24 | "Indhold fra denne side er overført direkte fra ældre wiki, og kan derfor " 25 | "være uddateret. Billeder er linket udenfor dette bibliotek." 26 | msgstr "" 27 | 28 | #: ../../_subs/WARNING_OLD_DOC.rst:5 9d090de83b0347819ec68bace5bfe0a5 29 | msgid "" 30 | "Du er velkommen til at hjælpe med at holde dokumentationen opdateret. Læs" 31 | " mere her" 32 | msgstr "" 33 | 34 | #: ../../_subs/WARNING_OLD_DOC.rst:7 a6841710a4e0447aafc64aa80bd3dacf 35 | msgid ":ref:`CONTRIBUTING`" 36 | msgstr "" 37 | 38 | -------------------------------------------------------------------------------- /docs/locales/en/LC_MESSAGES/pages/extensions/extensions.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) 2023, MapCentia 3 | # This file is distributed under the same license as the Vidi package. 4 | # FIRST AUTHOR , 2024. 5 | # 6 | #, fuzzy 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: Vidi 1.0\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "POT-Creation-Date: 2024-01-09 12:54+0100\n" 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 13 | "Last-Translator: FULL NAME \n" 14 | "Language: en\n" 15 | "Language-Team: en \n" 16 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 17 | "MIME-Version: 1.0\n" 18 | "Content-Type: text/plain; charset=utf-8\n" 19 | "Content-Transfer-Encoding: 8bit\n" 20 | "Generated-By: Babel 2.12.1\n" 21 | 22 | #: ../../pages/extensions/extensions.rst:9 afd2d09db1034da981e8c4bb21786b82 23 | msgid "Extensions" 24 | msgstr "" 25 | 26 | #: ../../pages/extensions/extensions.rst:9 c02e957d01be4b1aa883749338b70e4e 27 | msgid "Overview" 28 | msgstr "" 29 | 30 | #: ../../pages/extensions/extensions.rst 0b367b1e860e4ca883cc0f31eb52a646 31 | msgid "Date" 32 | msgstr "" 33 | 34 | #: ../../pages/extensions/extensions.rst:13 dc093f1b8f7e44049168f29f167faae6 35 | msgid "|today|" 36 | msgstr "" 37 | 38 | #: ../../pages/extensions/extensions.rst 94c86ccd870740f19eb09a490d95659b 39 | msgid "Vidi-version" 40 | msgstr "" 41 | 42 | #: ../../pages/extensions/extensions.rst:14 7d6b5cd3b31044898f4bd274f1c5015a 43 | msgid "UNRELEASED" 44 | msgstr "" 45 | 46 | #: ../../pages/extensions/extensions.rst e138496c4de84c44b1566d5a115310f5 47 | msgid "Forfattere" 48 | msgstr "" 49 | 50 | #: ../../pages/extensions/extensions.rst:15 31ec90787d99400c9c0e65f7139b6326 51 | msgid "`mapcentia `_" 52 | msgstr "" 53 | 54 | #: ../../pages/extensions/extensions.rst:18 e0d637bc98e34c15a8e21072c56b166e 55 | msgid "Indhold" 56 | msgstr "" 57 | 58 | #: ../../pages/extensions/extensions.rst:23 1280315369204079adc268c82f6fa04b 59 | msgid "Editering" 60 | msgstr "" 61 | 62 | #: ../../pages/extensions/extensions.rst:26 5944e145da104b4cbbf578b189a3afb2 63 | msgid "Introduktion" 64 | msgstr "" 65 | 66 | #: ../../pages/extensions/extensions.rst:35 bedec73b3a81497e9b3b9585b6f446f9 67 | msgid "meow" 68 | msgstr "" 69 | 70 | #: ../../pages/extensions/extensions.rst:35 4e9caffd50ae452e9c3ba71bb45f2507 71 | msgid "figure are like images but with a caption" 72 | msgstr "" 73 | 74 | -------------------------------------------------------------------------------- /docs/pages/extensions/extensions.rst: -------------------------------------------------------------------------------- 1 | .. _extensions: 2 | 3 | .. |gc2| raw:: html 4 | 5 | GC2 6 | 7 | ***************************************************************** 8 | Extensions 9 | ***************************************************************** 10 | 11 | .. topic:: Overview 12 | 13 | :Date: |today| 14 | :Vidi-version: UNRELEASED 15 | :Forfattere: `mapcentia `_ 16 | 17 | .. contents:: 18 | :depth: 3 19 | 20 | .. _extensions_directions: 21 | 22 | Rutevejledning 23 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 24 | 25 | ``directions`` er en udvidelse til vidi der giver mulighed for at lave rutevejledning i kortet. Der laves en rutevejledning fra brugerens position til et punkt på kortet. Det er i øjeblikket kun muligt at lave rutevejledning med Google Maps. 26 | 27 | Intallation 28 | """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 29 | 30 | Funktionen skal medtages i :ref:`configjs_extensions` 31 | 32 | .. code-block:: js 33 | 34 | extensions: { 35 | browser: [ 36 | {"directions": ["index"]}, 37 | ], 38 | }, 39 | 40 | 41 | Brug 42 | """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 43 | 44 | .. figure:: ../../_media/extensions-directions-icon.png 45 | :align: center 46 | :figclass: align-center 47 | 48 | ikon i :ref:`gettingstarted_controls` 49 | 50 | Start med at aktivere geolokation i :ref:`gettingstarted_controls` og klik på ikonet. Derefter klik på kortet for at vælge destinationen. Rutevejledningen vil åbne i et nyt vindue. -------------------------------------------------------------------------------- /docs/pages/extensions/non_standard.rst: -------------------------------------------------------------------------------- 1 | .. _non_standard_extensions: 2 | 3 | .. |gc2| raw:: html 4 | 5 | GC2 6 | 7 | ################################################################# 8 | Ikke-standard extensions 9 | ################################################################# 10 | 11 | .. topic:: Overview 12 | 13 | :Date: |today| 14 | :Author: `mapcentia `_ 15 | 16 | .. contents:: 17 | :depth: 3 18 | 19 | ***************************************************************** 20 | Introduktion 21 | ***************************************************************** 22 | 23 | Herunder findes dokumentation på nogle af de extensions, som ikke følger med Vidi som standard. Skal en af disse anvendes kræves det, at den bliver installeret. 24 | 25 | ***************************************************************** 26 | Rejsetid (otp) 27 | ***************************************************************** 28 | 29 | Rejsetid extensionen opsættes i en kørselskonfiguration (config) under :ref:`configjs_extensionconfig` 30 | 31 | ``routes`` er en liste med de grafer, som brugeren skal kunne vælge imellem i Vidi. 32 | 33 | ``default`` angiver start-værdier for de forskellige indstillinger i Vidi. Alle behøves ikke udfyldes. Hvis der undlades indstillinger, bliver der anvendt værdier, som svarer til de nedenunser viste. 34 | 35 | ``parameters`` angiver ekstra URL parametre, som skal sendes med til OTP serveren. Default bliver ingen parametre sat. 36 | 37 | ``helpText`` angiver den tekst, som skal vises i modulets hjælpefunktion. Default er en tom tekst. 38 | 39 | .. code-block:: json 40 | 41 | { 42 | "extensionConfig": { 43 | "otp": { 44 | "routes": ["default", "nt", "midttrafik", "sydtrafik"], 45 | "defaults": { 46 | "startTime": 30, 47 | "endTime": 50, 48 | "intervals": [600, 1200, 1800], 49 | "startColor": "#ff0000", 50 | "endColor": "#00ff00", 51 | "opacity": 0.7, 52 | "arriveBy": false, 53 | "route": "default", 54 | "maxWalkDistance": 500 55 | }, 56 | "parameters": { 57 | "offRoadDistanceMeters": "75", 58 | "precisionMeters": "100" 59 | }, 60 | "helpText": "Hjælp til OTP" 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /docs/pages/standard/07_print.rst: -------------------------------------------------------------------------------- 1 | .. _print: 2 | 3 | ################################################################# 4 | Print 5 | ################################################################# 6 | 7 | .. topic:: Overview 8 | 9 | :Date: |today| 10 | :Vidi-version: 2020.11.0 11 | :Forfatter: `giovanniborella `_ 12 | 13 | .. include:: ../../_subs/NOTE_CONF.rst 14 | 15 | .. contents:: 16 | :depth: 3 17 | 18 | 19 | ***************************************************************** 20 | Printværktøj 21 | ***************************************************************** 22 | 23 | .. include:: ../../_subs/NOTE_GETTINGSTARTED.rst 24 | 25 | Når værktøjet vælges er det indledningsvis tændt. 26 | 27 | Print 28 | ================================================================= 29 | 30 | Når værktøjet er tændt vil man se en rød kasser der representerer udskriftsområdet. 31 | 32 | .. figure:: ../../_media/print-on.png 33 | :width: 400px 34 | :align: center 35 | :name: print-on 36 | :figclass: align-center 37 | 38 | Værktøjet er tændt, og klar til at printe 39 | 40 | Muligheder 41 | ----------------------------------------------------------------- 42 | 43 | Efter print-området er dannet er det muligt i kortvinduet at: 44 | 45 | * Flytte området ved hjælp af punktet i midten. 46 | * Ændre målestoksforhold ved at trække i de yderste punkter. 47 | 48 | Følgende indstillinger kan også sættes: 49 | 50 | * Skabelon 51 | * Hvis der er defineret flere skabeloner i konfigurationen, vises disse her 52 | * Papirstørrelse 53 | * Her vælges den relevante papirstørrelse som er tilgængelig i skabelonen 54 | * Orientering 55 | * Der understøttes print i `Liggende` og `Stående` 56 | * Titel, Kommentar 57 | * Hvis disse felter, eller et af disse felder udfyldes vil der være et korthoved indeholdende teksterne på printet. 58 | * Vis signatur 59 | * Er denne slået til, vil der blive genereret en signatur over de de aktive lag på kortet. 60 | 61 | Når man er tilfreds med indstillingerne, klikker man på ``Lav PDF``. Det er også muligt at bruge drop-down til at printe som ``PNG`` 62 | 63 | .. figure:: ../../_media/print-ready.png 64 | :width: 400px 65 | :align: center 66 | :name: print-ready 67 | :figclass: align-center 68 | 69 | Klar til at printe 70 | 71 | .. figure:: ../../_media/print-complete.png 72 | :width: 400px 73 | :align: center 74 | :name: print-complete 75 | :figclass: align-center 76 | 77 | Print er gennemført 78 | 79 | Når printet er gennemført har man muligheden for at åbne printet i browseren - eller ved hjælp af drop-down; downloade printet eller få vist kortet i en HTML version. -------------------------------------------------------------------------------- /docs/pages/standard/80_standard_query_string.rst: -------------------------------------------------------------------------------- 1 | .. _standardquerystring: 2 | 3 | ################################################################# 4 | Standard query string 5 | ################################################################# 6 | 7 | .. topic:: Overview 8 | 9 | :Date: |today| 10 | :Vidi-version: 2022.8.4 11 | :Forfattere: `mapcentia `_ 12 | 13 | .. contents:: 14 | :depth: 4 15 | 16 | Når Vidi starter kan man indsætte parametre i url'en som styre en række egenskaber. 17 | 18 | initialFilter 19 | ***************************************************************** 20 | 21 | Denne parameter kan sætte filtre på lag således, at de er filtreret fra startet. Der kan sættes flere filtre på det samme lag og flere lag kan filtreres. Filtrede lag bliver aktiveret i vektor-udgave og der zoomes til filtrerede features på det sidst færdig-loadede lag. 22 | Hvis laget ikke er udgivet i vektor-udgave, vil tile-udgaven tænde og der zoomes ikke. 23 | 24 | Et filter objekt ser sådeles ud: 25 | 26 | .. code-block:: json 27 | 28 | { 29 | "kommuneplan_2017.k_plan_rammer": { 30 | "match": "any", 31 | "columns": [ 32 | { 33 | "fieldname": "id", 34 | "expression": "=", 35 | "value": "699737", 36 | "restriction": false 37 | } 38 | ] 39 | } 40 | } 41 | 42 | Når det skal bruges i URL'en skal filter objektet Base64URL kodes. Det ligner dette: 43 | 44 | .. code-block:: text 45 | 46 | ?initialFilter=ewogICJ0ZXN0Lm11bHRpcG9seWdvbiI6IHsKICAgICJtYXRjaCI6ICJhbn... 47 | 48 | .. note:: 49 | Base64URL er en afart af Base64, som ikke kan indeholde tegnene +=/ og er derfor "url sikker". https://www.npmjs.com/package/base64url 50 | -------------------------------------------------------------------------------- /docs/pages/standard/96_api.rst: -------------------------------------------------------------------------------- 1 | .. _api: 2 | 3 | ################################################################# 4 | Vidi API 5 | ################################################################# 6 | 7 | .. topic:: Overview 8 | 9 | :Date: |today| 10 | :Vidi-version: MASTER 11 | :Forfattere: `mapcentia `_ 12 | 13 | .. contents:: 14 | :depth: 4 15 | 16 | ***************************************************************** 17 | Brug 18 | ***************************************************************** 19 | 20 | APIet kan bruges i de forskellige templates og funktioner, der kan defineres forskellige steder i en Vidi opsætning. Fx i :ref:`gc2mata_infopopup` templates og funktioner. 21 | 22 | .. note:: 23 | APIet kan ikke bruges til indlejrede Vidi kort - dvs. på den webside som Vidi er indlejret på. Her henvises til :ref:`embed_api` 24 | 25 | Tænd lag (turnOn) 26 | ================================================================= 27 | 28 | Med denne metode kan man tænde for et lag. Den tager et argument som er et fuldt lagnavn med evt. type præfiks: 29 | 30 | .. code-block:: javascript 31 | 32 | api.turnOn("schema.lag"); 33 | 34 | Sluk lag (turnOff) 35 | ================================================================= 36 | 37 | Med denne metode kan man tænde for et lag. Den tager et argument som er et fuldt lagnavn med evt. type præfiks: 38 | 39 | .. code-block:: javascript 40 | 41 | api.turnOff("schema.lag"); 42 | 43 | Sæt filter på lag (filter) 44 | ================================================================= 45 | 46 | Med denne metode kan der sættes et filter på et givnet lag. Første argument er et fuldt lagnavn (uden type præfiks) og andet argument er filter objektet: 47 | 48 | .. code-block:: javascript 49 | 50 | api.filter("schema.lag", { 51 | "match": "any", 52 | "columns": [ 53 | { 54 | "fieldname": "gid", 55 | "expression": "=", 56 | "value": "1", 57 | "restriction": false 58 | } 59 | ] 60 | }) 61 | -------------------------------------------------------------------------------- /docs/requirements.txt: -------------------------------------------------------------------------------- 1 | sphinx==7.2 2 | m2r2 3 | sphinx-rtd-theme 4 | sphinx-intl 5 | sphinx-autobuild 6 | -------------------------------------------------------------------------------- /extensions/editor/browser/TimeWidget.jsx: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | // @ts-ignore 4 | var react_1 = require("react"); 5 | var utils_1 = require("@rjsf/utils"); 6 | /** The `TimeWidget` component uses the `BaseInputTemplate` changing the type to `time` and transforms 7 | * the value to undefined when it is falsy during the `onChange` handling. 8 | * 9 | * @param props - The `WidgetProps` for this component 10 | */ 11 | function TimeWidget(props) { 12 | var onChange = props.onChange, options = props.options, registry = props.registry; 13 | var BaseInputTemplate = (0, utils_1.getTemplate)("BaseInputTemplate", registry, options); 14 | var handleChange = (0, react_1.useCallback)(function (value) { return onChange(value || undefined); }, [onChange]); 15 | return ; 16 | } 17 | exports.default = TimeWidget; 18 | -------------------------------------------------------------------------------- /extensions/editor/browser/TimeWidget.tsx: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import React, { useCallback } from "react"; 3 | import { 4 | getTemplate, 5 | FormContextType, 6 | RJSFSchema, 7 | StrictRJSFSchema, 8 | WidgetProps, 9 | } from "@rjsf/utils"; 10 | 11 | /** The `TimeWidget` component uses the `BaseInputTemplate` changing the type to `time` and transforms 12 | * the value to undefined when it is falsy during the `onChange` handling. 13 | * 14 | * @param props - The `WidgetProps` for this component 15 | */ 16 | export default function TimeWidget< 17 | T = any, 18 | S extends StrictRJSFSchema = RJSFSchema, 19 | F extends FormContextType = any 20 | >(props: WidgetProps) { 21 | const { onChange, options, registry } = props; 22 | const BaseInputTemplate = getTemplate<"BaseInputTemplate", T, S, F>( 23 | "BaseInputTemplate", 24 | registry, 25 | options 26 | ); 27 | const handleChange = useCallback( 28 | (value: React.ChangeEvent) => onChange(value || undefined), 29 | [onChange] 30 | ); 31 | 32 | return ; 33 | } 34 | -------------------------------------------------------------------------------- /extensions/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Alexander Shumilov 3 | * @copyright 2013-2018 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | var express = require('express'); 8 | var router = express.Router(); 9 | var config = require('../config/config.js'); 10 | 11 | // Require extensions 12 | if (typeof config.extensions !== "undefined" && typeof config.extensions.server !== "undefined") { 13 | config.extensions.server.forEach(function (v, i) { 14 | v[Object.keys(v)[0]].forEach(function (m, n) { 15 | router.use(require('./' + Object.keys(v)[0] + '/server/' + m + ".js")); 16 | } 17 | ) 18 | } 19 | ); 20 | } 21 | module.exports = router; -------------------------------------------------------------------------------- /extensions/languages/browser/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Martin Høgh 3 | * @copyright 2013-2018 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | 'use strict'; 8 | 9 | /** 10 | * 11 | * @type {*|exports|module.exports} 12 | */ 13 | 14 | 15 | /** 16 | * 17 | * @type {*|exports|module.exports} 18 | */ 19 | var utils; 20 | 21 | /** 22 | * 23 | * @type {*|exports|module.exports} 24 | */ 25 | var backboneEvents; 26 | 27 | /** 28 | * 29 | */ 30 | var anchor; 31 | 32 | /** 33 | * 34 | * @type {string} 35 | */ 36 | var exId = "languages"; 37 | 38 | /** 39 | * 40 | * @type {{set: module.exports.set, init: module.exports.init}} 41 | */ 42 | 43 | module.exports = { 44 | 45 | /** 46 | * 47 | * @param o 48 | * @returns {exports} 49 | */ 50 | set: function (o) { 51 | utils = o.utils; 52 | anchor = o.anchor; 53 | backboneEvents = o.backboneEvents; 54 | return this; 55 | }, 56 | 57 | /** 58 | * 59 | */ 60 | init: function () { 61 | var ul, languages = require("../../../config/config.js").extensionConfig.languages; 62 | 63 | utils.createNavItem(exId, true); 64 | 65 | $('' + __("Languages") + '').appendTo('#' + exId); 66 | 67 | ul = $('').appendTo('#' + exId); 68 | 69 | $.each(languages, function (i, v) { 70 | ul.append('
  • ' + v.txt + '
  • '); 71 | }); 72 | 73 | $("[data-gc2-language]").on("click", function (e) { 74 | var locale = $(this).data('gc2-language'), 75 | url = anchor.getUri(languages[locale].schema) + "?" + anchor.getParam() + "&locale=" + locale + anchor.getAnchor(languages[locale].schema); 76 | location.href = url; 77 | }); 78 | } 79 | }; 80 | 81 | -------------------------------------------------------------------------------- /extensions/offlineMap/browser/components/LoadingOverlay.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Alexander Shumilov 3 | * @copyright 2013-2018 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | var React = require('react'); 8 | 9 | /** 10 | * MapAreaListItem component 11 | */ 12 | 13 | class MapAreaListItem extends React.Component { 14 | constructor(props) { 15 | super(props); 16 | } 17 | 18 | render() { 19 | let overlayStyle = { 20 | position: 'absolute', 21 | width: '100%', 22 | height: '100%', 23 | backgroundColor: 'rgba(255, 255, 255, 0.9)', 24 | zIndex: '1000' 25 | }; 26 | 27 | let overlayContentStyle = { 28 | top: '40px', 29 | textAlign: 'center', 30 | position: 'relative', 31 | padding: '40px' 32 | }; 33 | 34 | let content = false; 35 | if (this.props.tilesLoaded === this.props.tilesLeftToLoad) { 36 | content = (
    37 |

    {__("Done")}

    38 | {this.props.children} 39 |
    ); 40 | } else { 41 | let failedTilesWarning = false; 42 | if (this.props.tilesFailed > 0) { 43 | failedTilesWarning = (
    {this.props.tilesFailed} {__("tiles failed to load")}
    ); 44 | } 45 | 46 | content = (
    47 |

    {__("Processing tiles")} ({this.props.tilesLoaded} {__("of")} {this.props.tilesLeftToLoad})

    48 |
    49 |
    50 |
    51 | {failedTilesWarning} 52 |
    ); 53 | } 54 | 55 | return (
    56 |
    {content}
    57 |
    ); 58 | } 59 | } 60 | 61 | module.exports = MapAreaListItem; -------------------------------------------------------------------------------- /extensions/offlineMap/browser/components/MapAreaList.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @author Alexander Shumilov 3 | * @copyright 2013-2018 MapCentia ApS 4 | * @license http://www.gnu.org/licenses/#AGPL GNU AFFERO GENERAL PUBLIC LICENSE 3 5 | */ 6 | 7 | const React = require('react'); 8 | const MapAreaListItem = require('./MapAreaListItem'); 9 | 10 | /** 11 | * MapAreaListItem component 12 | */ 13 | 14 | class MapAreaList extends React.Component { 15 | constructor(props) { 16 | super(props); 17 | 18 | this.mapObj = props.mapObj; 19 | this.state = { 20 | areaItems: (props.items ? this.itemsObjectToArray(props.items) : []) 21 | }; 22 | } 23 | 24 | itemsObjectToArray(propItems) { 25 | let items = []; 26 | if (propItems) { 27 | for (let key in propItems) { 28 | items.push({ 29 | id: key, 30 | data: propItems[key] 31 | }); 32 | } 33 | } 34 | 35 | return items; 36 | } 37 | 38 | UNSAFE_componentWillReceiveProps(nextProps) { 39 | this.setState({ areaItems: this.itemsObjectToArray(nextProps.items) }); 40 | } 41 | 42 | onRefreshHandler(item) { 43 | this.props.onMapAreaRefresh(item); 44 | } 45 | 46 | onDeleteHandler(item) { 47 | this.props.onMapAreaDelete(item); 48 | } 49 | 50 | render() { 51 | if (this.state.areaItems.length === 0) { 52 | return (
    {__("No map areas have been stored yet")}
    ); 53 | } else { 54 | let renderedItems = []; 55 | this.state.areaItems.map((item, index) => { 56 | renderedItems.push(); 63 | }); 64 | 65 | return ( 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | {renderedItems} 74 |
    {__("Info")}{__("Comment")}{__("Actions")}
    ); 75 | } 76 | } 77 | } 78 | 79 | module.exports = MapAreaList; -------------------------------------------------------------------------------- /extensions/symbols/script/parse.py: -------------------------------------------------------------------------------- 1 | from xml.dom import minidom 2 | import sys 3 | import json 4 | from os import listdir 5 | from os.path import isfile, join 6 | 7 | walk_dir = sys.argv[1] 8 | symbols = {} 9 | 10 | only_files = [f for f in sorted(listdir(walk_dir)) if isfile(join(walk_dir, f))] 11 | 12 | for file in only_files: 13 | try: 14 | full_path = walk_dir + "/" + file 15 | doc = minidom.parse(full_path) 16 | # Remove width and height 17 | for c in doc.childNodes: 18 | try: 19 | c.removeAttribute("width") 20 | c.removeAttribute("height") 21 | except Exception as e: 22 | pass 23 | # print(e) 24 | output_xml = ''.join([line.strip() for line in doc.toxml().splitlines()]) 25 | symbols[file] = {"svg": output_xml} 26 | doc.unlink() 27 | except: 28 | pass 29 | 30 | print(json.dumps(symbols)) 31 | exit(0) 32 | -------------------------------------------------------------------------------- /karma.config.js: -------------------------------------------------------------------------------- 1 | process.env.CHROME_BIN = require("puppeteer").executablePath(); 2 | 3 | module.exports = function(config) { 4 | config.set({ 5 | frameworks: ["mocha", "chai"], 6 | files: ["test/**/*.test.js"], 7 | reporters: ["progress"], 8 | port: 9876, // karma web server port 9 | colors: true, 10 | logLevel: config.LOG_INFO, 11 | browsers: ["ChromeHeadless", "ChromeHeadless_no_sandbox"], 12 | autoWatch: false, 13 | plugins: ["karma-webpack", "karma-browserify", "karma-mocha", "karma-chai"], 14 | // singleRun: false, // Karma captures browsers, runs the tests and exits 15 | concurrency: Infinity, 16 | customLaunchers: { 17 | ChromeHeadless_no_sandbox: { 18 | base: "ChromeHeadless", 19 | flags: ["--no-sandbox"] 20 | } 21 | } 22 | }); 23 | }; 24 | -------------------------------------------------------------------------------- /public/api/config/aleksandrshumilov/aleksandrshumilov.json: -------------------------------------------------------------------------------- 1 | { 2 | "brandName": "Test" 3 | } -------------------------------------------------------------------------------- /public/api/config/vidi.json: -------------------------------------------------------------------------------- 1 | { 2 | "brandName": "Test" 3 | } -------------------------------------------------------------------------------- /public/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | #00aba9 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /public/connection-check.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/connection-check.ico -------------------------------------------------------------------------------- /public/css/webfonts/fa-brands-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/css/webfonts/fa-brands-400.eot -------------------------------------------------------------------------------- /public/css/webfonts/fa-brands-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/css/webfonts/fa-brands-400.ttf -------------------------------------------------------------------------------- /public/css/webfonts/fa-brands-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/css/webfonts/fa-brands-400.woff -------------------------------------------------------------------------------- /public/css/webfonts/fa-brands-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/css/webfonts/fa-brands-400.woff2 -------------------------------------------------------------------------------- /public/css/webfonts/fa-regular-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/css/webfonts/fa-regular-400.eot -------------------------------------------------------------------------------- /public/css/webfonts/fa-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/css/webfonts/fa-regular-400.ttf -------------------------------------------------------------------------------- /public/css/webfonts/fa-regular-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/css/webfonts/fa-regular-400.woff -------------------------------------------------------------------------------- /public/css/webfonts/fa-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/css/webfonts/fa-regular-400.woff2 -------------------------------------------------------------------------------- /public/css/webfonts/fa-solid-900.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/css/webfonts/fa-solid-900.eot -------------------------------------------------------------------------------- /public/css/webfonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/css/webfonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /public/css/webfonts/fa-solid-900.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/css/webfonts/fa-solid-900.woff -------------------------------------------------------------------------------- /public/css/webfonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/css/webfonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /public/css/webfonts/fa-v4compatibility.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/css/webfonts/fa-v4compatibility.ttf -------------------------------------------------------------------------------- /public/css/webfonts/fa-v4compatibility.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/css/webfonts/fa-v4compatibility.woff2 -------------------------------------------------------------------------------- /public/favicon.ico.default: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/favicon.ico.default -------------------------------------------------------------------------------- /public/fonts/cJZKeOuBrn4kERxqtaUH3bO3LdcAZYWl9Si6vvxL-qU.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/fonts/cJZKeOuBrn4kERxqtaUH3bO3LdcAZYWl9Si6vvxL-qU.woff -------------------------------------------------------------------------------- /public/fonts/fa-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/fonts/fa-regular-400.ttf -------------------------------------------------------------------------------- /public/fonts/fa-regular-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/fonts/fa-regular-400.woff -------------------------------------------------------------------------------- /public/fonts/fa-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/fonts/fa-regular-400.woff2 -------------------------------------------------------------------------------- /public/fonts/fa-solid-900.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/fonts/fa-solid-900.eot -------------------------------------------------------------------------------- /public/fonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/fonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /public/fonts/fa-solid-900.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/fonts/fa-solid-900.woff -------------------------------------------------------------------------------- /public/fonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/fonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /public/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /public/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /public/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /public/fonts/roboto-v18-latin-300.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/fonts/roboto-v18-latin-300.eot -------------------------------------------------------------------------------- /public/fonts/roboto-v18-latin-300.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/fonts/roboto-v18-latin-300.ttf -------------------------------------------------------------------------------- /public/fonts/roboto-v18-latin-300.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/fonts/roboto-v18-latin-300.woff -------------------------------------------------------------------------------- /public/fonts/roboto-v18-latin-300.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/fonts/roboto-v18-latin-300.woff2 -------------------------------------------------------------------------------- /public/fonts/roboto-v18-latin-500.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/fonts/roboto-v18-latin-500.eot -------------------------------------------------------------------------------- /public/fonts/roboto-v18-latin-500.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/fonts/roboto-v18-latin-500.ttf -------------------------------------------------------------------------------- /public/fonts/roboto-v18-latin-500.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/fonts/roboto-v18-latin-500.woff -------------------------------------------------------------------------------- /public/fonts/roboto-v18-latin-500.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/fonts/roboto-v18-latin-500.woff2 -------------------------------------------------------------------------------- /public/fonts/roboto-v18-latin-700.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/fonts/roboto-v18-latin-700.eot -------------------------------------------------------------------------------- /public/fonts/roboto-v18-latin-700.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/fonts/roboto-v18-latin-700.ttf -------------------------------------------------------------------------------- /public/fonts/roboto-v18-latin-700.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/fonts/roboto-v18-latin-700.woff -------------------------------------------------------------------------------- /public/fonts/roboto-v18-latin-700.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/fonts/roboto-v18-latin-700.woff2 -------------------------------------------------------------------------------- /public/fonts/roboto-v18-latin-900.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/fonts/roboto-v18-latin-900.eot -------------------------------------------------------------------------------- /public/fonts/roboto-v18-latin-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/fonts/roboto-v18-latin-900.ttf -------------------------------------------------------------------------------- /public/fonts/roboto-v18-latin-900.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/fonts/roboto-v18-latin-900.woff -------------------------------------------------------------------------------- /public/fonts/roboto-v18-latin-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/fonts/roboto-v18-latin-900.woff2 -------------------------------------------------------------------------------- /public/fonts/roboto-v18-latin-italic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/fonts/roboto-v18-latin-italic.eot -------------------------------------------------------------------------------- /public/fonts/roboto-v18-latin-italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/fonts/roboto-v18-latin-italic.ttf -------------------------------------------------------------------------------- /public/fonts/roboto-v18-latin-italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/fonts/roboto-v18-latin-italic.woff -------------------------------------------------------------------------------- /public/fonts/roboto-v18-latin-italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/fonts/roboto-v18-latin-italic.woff2 -------------------------------------------------------------------------------- /public/fonts/roboto-v18-latin-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/fonts/roboto-v18-latin-regular.eot -------------------------------------------------------------------------------- /public/fonts/roboto-v18-latin-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/fonts/roboto-v18-latin-regular.ttf -------------------------------------------------------------------------------- /public/fonts/roboto-v18-latin-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/fonts/roboto-v18-latin-regular.woff -------------------------------------------------------------------------------- /public/fonts/roboto-v18-latin-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/fonts/roboto-v18-latin-regular.woff2 -------------------------------------------------------------------------------- /public/images/192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/images/192x192.png -------------------------------------------------------------------------------- /public/images/48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/images/48x48.png -------------------------------------------------------------------------------- /public/images/512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/images/512x512.png -------------------------------------------------------------------------------- /public/images/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/images/favicon-16x16.png -------------------------------------------------------------------------------- /public/images/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/images/favicon-32x32.png -------------------------------------------------------------------------------- /public/js/lib/Leaflet.awesome-markers/images/markers-matte.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/Leaflet.awesome-markers/images/markers-matte.png -------------------------------------------------------------------------------- /public/js/lib/Leaflet.awesome-markers/images/markers-matte@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/Leaflet.awesome-markers/images/markers-matte@2x.png -------------------------------------------------------------------------------- /public/js/lib/Leaflet.awesome-markers/images/markers-plain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/Leaflet.awesome-markers/images/markers-plain.png -------------------------------------------------------------------------------- /public/js/lib/Leaflet.awesome-markers/images/markers-shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/Leaflet.awesome-markers/images/markers-shadow.png -------------------------------------------------------------------------------- /public/js/lib/Leaflet.awesome-markers/images/markers-shadow@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/Leaflet.awesome-markers/images/markers-shadow@2x.png -------------------------------------------------------------------------------- /public/js/lib/Leaflet.awesome-markers/images/markers-soft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/Leaflet.awesome-markers/images/markers-soft.png -------------------------------------------------------------------------------- /public/js/lib/Leaflet.awesome-markers/images/markers-soft@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/Leaflet.awesome-markers/images/markers-soft@2x.png -------------------------------------------------------------------------------- /public/js/lib/Leaflet.extra-markers/img/markers_default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/Leaflet.extra-markers/img/markers_default.png -------------------------------------------------------------------------------- /public/js/lib/Leaflet.extra-markers/img/markers_default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/Leaflet.extra-markers/img/markers_default@2x.png -------------------------------------------------------------------------------- /public/js/lib/Leaflet.extra-markers/img/markers_shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/Leaflet.extra-markers/img/markers_shadow.png -------------------------------------------------------------------------------- /public/js/lib/Leaflet.extra-markers/img/markers_shadow@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/Leaflet.extra-markers/img/markers_shadow@2x.png -------------------------------------------------------------------------------- /public/js/lib/Leaflet.markercluster/MarkerCluster.Default.css: -------------------------------------------------------------------------------- 1 | .marker-cluster-small { 2 | background-color: rgba(181, 226, 140, 0.6); 3 | } 4 | .marker-cluster-small div { 5 | background-color: rgba(110, 204, 57, 0.6); 6 | } 7 | 8 | .marker-cluster-medium { 9 | background-color: rgba(241, 211, 87, 0.6); 10 | } 11 | .marker-cluster-medium div { 12 | background-color: rgba(240, 194, 12, 0.6); 13 | } 14 | 15 | .marker-cluster-large { 16 | background-color: rgba(253, 156, 115, 0.6); 17 | } 18 | .marker-cluster-large div { 19 | background-color: rgba(241, 128, 23, 0.6); 20 | } 21 | 22 | /* IE 6-8 fallback colors */ 23 | .leaflet-oldie .marker-cluster-small { 24 | background-color: rgb(181, 226, 140); 25 | } 26 | .leaflet-oldie .marker-cluster-small div { 27 | background-color: rgb(110, 204, 57); 28 | } 29 | 30 | .leaflet-oldie .marker-cluster-medium { 31 | background-color: rgb(241, 211, 87); 32 | } 33 | .leaflet-oldie .marker-cluster-medium div { 34 | background-color: rgb(240, 194, 12); 35 | } 36 | 37 | .leaflet-oldie .marker-cluster-large { 38 | background-color: rgb(253, 156, 115); 39 | } 40 | .leaflet-oldie .marker-cluster-large div { 41 | background-color: rgb(241, 128, 23); 42 | } 43 | 44 | .marker-cluster { 45 | background-clip: padding-box; 46 | border-radius: 20px; 47 | } 48 | .marker-cluster div { 49 | width: 30px; 50 | height: 30px; 51 | margin-left: 5px; 52 | margin-top: 5px; 53 | 54 | text-align: center; 55 | border-radius: 15px; 56 | font: 12px "Helvetica Neue", Arial, Helvetica, sans-serif; 57 | } 58 | .marker-cluster span { 59 | line-height: 30px; 60 | } -------------------------------------------------------------------------------- /public/js/lib/Leaflet.markercluster/MarkerCluster.css: -------------------------------------------------------------------------------- 1 | .leaflet-cluster-anim .leaflet-marker-icon, .leaflet-cluster-anim .leaflet-marker-shadow { 2 | -webkit-transition: -webkit-transform 0.3s ease-out, opacity 0.3s ease-in; 3 | -moz-transition: -moz-transform 0.3s ease-out, opacity 0.3s ease-in; 4 | -o-transition: -o-transform 0.3s ease-out, opacity 0.3s ease-in; 5 | transition: transform 0.3s ease-out, opacity 0.3s ease-in; 6 | } 7 | 8 | .leaflet-cluster-spider-leg { 9 | /* stroke-dashoffset (duration and function) should match with leaflet-marker-icon transform in order to track it exactly */ 10 | -webkit-transition: -webkit-stroke-dashoffset 0.3s ease-out, -webkit-stroke-opacity 0.3s ease-in; 11 | -moz-transition: -moz-stroke-dashoffset 0.3s ease-out, -moz-stroke-opacity 0.3s ease-in; 12 | -o-transition: -o-stroke-dashoffset 0.3s ease-out, -o-stroke-opacity 0.3s ease-in; 13 | transition: stroke-dashoffset 0.3s ease-out, stroke-opacity 0.3s ease-in; 14 | } 15 | -------------------------------------------------------------------------------- /public/js/lib/Path.Drag.js/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Path.Drag.js", 3 | "homepage": "https://github.com/Leaflet/Path.Drag.js", 4 | "version": "0.0.6", 5 | "_release": "0.0.6", 6 | "_resolution": { 7 | "type": "version", 8 | "tag": "0.0.6", 9 | "commit": "a15c06a3d7babd8ebe4bbdcf6037c72b93c18aa6" 10 | }, 11 | "_source": "https://github.com/Leaflet/Path.Drag.js.git", 12 | "_target": "^0.0.6", 13 | "_originalSource": "https://github.com/Leaflet/Path.Drag.js.git" 14 | } -------------------------------------------------------------------------------- /public/js/lib/Path.Drag.js/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /public/js/lib/Path.Drag.js/README.md: -------------------------------------------------------------------------------- 1 | # Path.Drag.js 2 | 3 | Add dragging capability to Leaflet path (Polygon, Polyline, Rectangle, Circle, CircleMarker…). 4 | 5 | 6 | ## Example 7 | 8 | - [simple example](http://Leaflet.github.io/Path.Drag.js/example/index.html) 9 | - [huge polygon example](http://Leaflet.github.io/Path.Drag.js/example/russia.html) 10 | - [canvas example](http://Leaflet.github.io/Path.Drag.js/example/canvas.html) 11 | 12 | 13 | ## Installation 14 | 15 | **This library requires Leaflet version 1.0 or above** 16 | 17 | Include `Path.Drag.js` in your javascript files (after including Leaflet itself). 18 | 19 | It's available via NPM: 20 | 21 | npm install leaflet.path.drag 22 | 23 | 24 | ## Usage 25 | 26 | A `dragging` handler will be attached to the paths instance of your map. 27 | To enable dragging, just do: 28 | 29 | layer.dragging.enable() 30 | 31 | To disable: 32 | 33 | layer.dragging.disable() 34 | 35 | 36 | If you want a path to be draggable as soon as it's added to map, add 37 | `draggable: true` to its options: 38 | 39 | const layer = L.polygon([…], {draggable: true}) 40 | 41 | 42 | ## Alternatives: 43 | 44 | - https://github.com/w8r/Leaflet.Path.Drag: use it if you want to drag very big path 45 | with many vertices. 46 | -------------------------------------------------------------------------------- /public/js/lib/Path.Drag.js/example/canvas.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Path.Drag.js demo 5 | 6 | 7 | 8 | 9 | 24 | 25 | 26 | 27 |
    28 | 29 | 30 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /public/js/lib/Path.Drag.js/example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Path.Drag.js demo 5 | 6 | 7 | 8 | 9 | 24 | 25 | 26 | 27 |
    28 | 29 | 30 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /public/js/lib/Path.Drag.js/example/russia.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Path.Drag.js demo 5 | 6 | 7 | 8 | 9 | 10 | 25 | 26 | 27 | 28 |
    29 | 30 | 31 | 51 | 52 | -------------------------------------------------------------------------------- /public/js/lib/Path.Drag.js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "leaflet.path.drag", 3 | "version": "0.0.6", 4 | "description": "Allow to drag Leaflet path", 5 | "main": "src/Path.Drag.js", 6 | "scripts": { 7 | "test": "./node_modules/phantomjs-prebuilt/bin/phantomjs node_modules/mocha-phantomjs-core/mocha-phantomjs-core.js test/index.html spec '{\"viewportSize\":{\"width\": 1024,\"height\": 768}}'" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/Leaflet/Path.Drag.js.git" 12 | }, 13 | "keywords": [ 14 | "leaflet", 15 | "path", 16 | "polygon", 17 | "polyline", 18 | "dragging" 19 | ], 20 | "author": "Yohan Boniface", 21 | "license": "MIT", 22 | "bugs": { 23 | "url": "https://github.com/Leaflet/Path.Drag.js/issues" 24 | }, 25 | "homepage": "https://github.com/Leaflet/Path.Drag.js#readme", 26 | "devDependencies": { 27 | "chai": "^3.5.0", 28 | "leaflet": "^1.2.0", 29 | "mocha": "^2.5.3", 30 | "mocha-phantomjs-core": "^1.3.1", 31 | "phantomjs-prebuilt": "^2.1.7", 32 | "prosthetic-hand": "^1.3.1" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /public/js/lib/Path.Drag.js/test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | L.Handler.PathDrag Tests 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 38 | 39 | 40 |
    41 |
    42 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /public/js/lib/bootstrap-colorpicker/css/bootstrap-colorpicker.min.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["src/less/colorpicker.less"],"names":[],"mappings":";;;;;;;;AAqBA,wBACE,MAAA,MACA,OAAA,MAXA,iBAAsB,iDAatB,OAAA,UACA,MAAA,KACA,0BACE,QAAA,MACA,OAAA,IACA,MAAA,IACA,OAAA,IAAA,MAAA,KAfF,sBAAA,IACA,mBAAA,IACA,cAAA,IAeE,SAAA,SACA,IAAA,EACA,KAAA,EACA,OAAA,KAAA,EAAA,EAAA,KACA,4BACE,QAAA,MACA,OAAA,IACA,MAAA,IACA,OAAA,IAAA,MAAA,KAzBJ,sBAAA,IACA,mBAAA,IACA,cAAA,IA8BF,mBADA,iBAEE,MAAA,KACA,OAAA,MACA,MAAA,KACA,OAAA,WACA,YAAA,IACA,cAAA,IAIiB,qBADF,mBAEf,QAAA,MACA,OAAA,IACA,WAAA,KACA,WAAA,IAAA,MAAA,KACA,SAAA,SACA,IAAA,EACA,KAAA,EACA,MAAA,KACA,WAAA,KAGF,iBA1DE,iBAAsB,0CA8DxB,mBA9DE,iBAAsB,4CAgEtB,QAAA,KAKF,mBADA,iBADA,wBAGE,gBAAA,QAGF,aACE,QAAA,IACA,UAAA,MACA,WAAA,IAxEA,sBAAA,IACA,mBAAA,IACA,cAAA,IAwEA,QAAA,KAIU,mBADA,oBAEV,QAAA,MACA,QAAA,GACA,YAAA,EAGU,mBACV,MAAA,KAGU,oBACV,QAAA,GACA,QAAA,aACA,YAAA,IAAA,MAAA,YACA,aAAA,IAAA,MAAA,YACA,cAAA,IAAA,MAAA,KACA,oBAAA,eACA,SAAA,SACA,IAAA,KACA,KAAA,IAGU,mBACV,QAAA,GACA,QAAA,aACA,YAAA,IAAA,MAAA,YACA,aAAA,IAAA,MAAA,YACA,cAAA,IAAA,MAAA,KACA,SAAA,SACA,IAAA,KACA,KAAA,IAGW,iBACX,SAAA,SAGU,oCACV,UAAA,MAGkC,uDAClC,QAAA,MAGF,mBACE,OAAA,KACA,WAAA,IACA,MAAA,KAlIA,iBAAsB,4CAoItB,oBAAA,EAAA,KAGiB,uBACjB,OAAA,KAGF,uBACE,QAAA,KACA,OAAA,KACA,WAAA,IACA,MAAA,KAGqB,yBACrB,OAAA,QACA,MAAA,KACA,OAAA,KACA,MAAA,KAGuB,2BACvB,YAAA,IAI2B,+BADW,0CAEtC,QAAA,aACA,OAAA,QACA,OAAA,KACA,eAAA,SACA,MAAA,KAGU,gCACV,SAAA,SACA,QAAA,aACA,MAAA,KACA,QAAA,KAGU,oCACV,MAAA,MACA,UAAA,MACA,OAAA,KAGkC,4DAClC,cAAA,IAGkC,uDAClC,MAAA,MAIkC,uDADA,qDAElC,MAAA,MACA,OAAA,KACA,MAAA,KACA,OAAA,WACA,YAAA,EACA,cAAA,IAIqD,yDADF,uDAEnD,QAAA,MACA,OAAA,KACA,WAAA,KACA,SAAA,SACA,IAAA,EACA,KAAA,EACA,MAAA,IACA,OAAA,KACA,WAAA,EAGkC,qDAlNlC,iBAAsB,qDAsNY,uDAtNlC,iBAAsB,uDA0NN,0BAChB,KAAA,KACA,MAAA,IAGgB,yBAChB,KAAA,KACA,MAAA,IAGmB,6BACnB,aAAA,EACA,YAAA,EAGmB,4BACnB,aAAA,EACA,YAAA,EAQC,uCAAA,qCAAA,4CAAA,2CAAA,iCACC,QAAA,MASD,sCAAA,oCAAA,2CAAA,0CAAA,gCACC,QAAA,KAIe,wCACjB,QAAA"} -------------------------------------------------------------------------------- /public/js/lib/bootstrap-colorpicker/img/bootstrap-colorpicker/alpha-horizontal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/bootstrap-colorpicker/img/bootstrap-colorpicker/alpha-horizontal.png -------------------------------------------------------------------------------- /public/js/lib/bootstrap-colorpicker/img/bootstrap-colorpicker/alpha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/bootstrap-colorpicker/img/bootstrap-colorpicker/alpha.png -------------------------------------------------------------------------------- /public/js/lib/bootstrap-colorpicker/img/bootstrap-colorpicker/hue-horizontal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/bootstrap-colorpicker/img/bootstrap-colorpicker/hue-horizontal.png -------------------------------------------------------------------------------- /public/js/lib/bootstrap-colorpicker/img/bootstrap-colorpicker/hue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/bootstrap-colorpicker/img/bootstrap-colorpicker/hue.png -------------------------------------------------------------------------------- /public/js/lib/bootstrap-colorpicker/img/bootstrap-colorpicker/saturation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/bootstrap-colorpicker/img/bootstrap-colorpicker/saturation.png -------------------------------------------------------------------------------- /public/js/lib/hogan.js/hogan.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 Twitter, Inc. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | // This file is for use with Node.js. See dist/ for browser files. 17 | 18 | var Hogan = require('./compiler'); 19 | Hogan.Template = require('./template').Template; 20 | Hogan.template = Hogan.Template; 21 | module.exports = Hogan; 22 | -------------------------------------------------------------------------------- /public/js/lib/leaflet-boxzoom/leaflet-boxzoom.css: -------------------------------------------------------------------------------- 1 | /* 2 | * BOXZOOM 3 | */ 4 | 5 | .leaflet-control-boxzoom.leaflet-control-boxzoom-active { 6 | background-color:#aaaaaa; 7 | } 8 | 9 | .leaflet-control-boxzoom.leaflet-control-boxzoom-active a { 10 | background-color: lightgray; 11 | } 12 | 13 | .leaflet-container.leaflet-control-boxzoom-active { 14 | cursor:crosshair !important; 15 | } 16 | -------------------------------------------------------------------------------- /public/js/lib/leaflet-dash-flow/L.Path.DashFlow.js: -------------------------------------------------------------------------------- 1 | // @class PolyLine 2 | 3 | L.Path.mergeOptions({ 4 | // @option dashSpeed: Number 5 | // The speed of the dash array, in pixels per second 6 | dashSpeed: 0 7 | }); 8 | 9 | 10 | var _originalBeforeAdd = L.Path.prototype.beforeAdd; 11 | 12 | L.Path.include({ 13 | 14 | beforeAdd: function (map) { 15 | _originalBeforeAdd.bind(this)(map); 16 | 17 | if (this.options.dashSpeed) { 18 | this._lastDashFrame = performance.now(); 19 | this._dashFrame = L.Util.requestAnimFrame(this._onDashFrame.bind(this)); 20 | } 21 | }, 22 | 23 | _onDashFrame: function(){ 24 | if (!this._renderer) { 25 | return; 26 | } 27 | 28 | var now = performance.now(); 29 | var dashOffsetDelta = (now - this._lastDashFrame) * this.options.dashSpeed / 1000; 30 | 31 | this.options.dashOffset = Number(this.options.dashOffset || 0) + dashOffsetDelta; 32 | this._renderer._updateStyle(this); 33 | 34 | this._lastDashFrame = performance.now(); 35 | 36 | this._dashFrame = L.Util.requestAnimFrame(this._onDashFrame.bind(this)); 37 | } 38 | 39 | }); 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /public/js/lib/leaflet-draw/images/layers-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/leaflet-draw/images/layers-2x.png -------------------------------------------------------------------------------- /public/js/lib/leaflet-draw/images/layers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/leaflet-draw/images/layers.png -------------------------------------------------------------------------------- /public/js/lib/leaflet-draw/images/marker-icon-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/leaflet-draw/images/marker-icon-2x.png -------------------------------------------------------------------------------- /public/js/lib/leaflet-draw/images/marker-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/leaflet-draw/images/marker-icon.png -------------------------------------------------------------------------------- /public/js/lib/leaflet-draw/images/marker-shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/leaflet-draw/images/marker-shadow.png -------------------------------------------------------------------------------- /public/js/lib/leaflet-draw/images/spritesheet-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/leaflet-draw/images/spritesheet-2x.png -------------------------------------------------------------------------------- /public/js/lib/leaflet-draw/images/spritesheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/leaflet-draw/images/spritesheet.png -------------------------------------------------------------------------------- /public/js/lib/leaflet-draw/spritesheet-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/leaflet-draw/spritesheet-2x.png -------------------------------------------------------------------------------- /public/js/lib/leaflet-draw/spritesheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/leaflet-draw/spritesheet.png -------------------------------------------------------------------------------- /public/js/lib/leaflet-history/leaflet-history.css: -------------------------------------------------------------------------------- 1 | .history-control.leaflet-bar.hidden{display:none}.history-control.leaflet-bar.horizontal a{display:inline-block;border-bottom:0;border-radius:0;border-right:1px solid #ccc}.history-control.leaflet-bar.horizontal a:first-child{border-top-left-radius:4px;border-bottom-left-radius:4px}.history-control.leaflet-bar.horizontal a:last-child{border-top-right-radius:4px;border-bottom-right-radius:4px;border-right:0}.history-control.leaflet-bar a{font-size:1.1em;min-width:26px} -------------------------------------------------------------------------------- /public/js/lib/leaflet-measure-path/leaflet-measure-path.css: -------------------------------------------------------------------------------- 1 | .leaflet-measure-path-measurement { 2 | position: absolute; 3 | font-size: 10px; 4 | color: black; 5 | text-shadow: -1px 0 0 white, 6 | -1px -1px 0 white, 7 | 0 -1px 0 white, 8 | 1px -1px 0 white, 9 | 1px 0 0 white, 10 | 1px 1px 0 white, 11 | 0 1px 0 white, 12 | -1px 1px 0 white; 13 | white-space: nowrap; 14 | transform-origin: 0; 15 | } 16 | 17 | .leaflet-measure-path-measurement > div { 18 | position: relative; 19 | margin-top: -25%; 20 | left: -50%; 21 | } 22 | -------------------------------------------------------------------------------- /public/js/lib/leaflet-measure/images/cancel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/leaflet-measure/images/cancel.png -------------------------------------------------------------------------------- /public/js/lib/leaflet-measure/images/cancel_@2X.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/leaflet-measure/images/cancel_@2X.png -------------------------------------------------------------------------------- /public/js/lib/leaflet-measure/images/check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/leaflet-measure/images/check.png -------------------------------------------------------------------------------- /public/js/lib/leaflet-measure/images/check_@2X.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/leaflet-measure/images/check_@2X.png -------------------------------------------------------------------------------- /public/js/lib/leaflet-measure/images/focus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/leaflet-measure/images/focus.png -------------------------------------------------------------------------------- /public/js/lib/leaflet-measure/images/focus_@2X.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/leaflet-measure/images/focus_@2X.png -------------------------------------------------------------------------------- /public/js/lib/leaflet-measure/images/rulers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/leaflet-measure/images/rulers.png -------------------------------------------------------------------------------- /public/js/lib/leaflet-measure/images/rulers_@2X.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/leaflet-measure/images/rulers_@2X.png -------------------------------------------------------------------------------- /public/js/lib/leaflet-measure/images/start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/leaflet-measure/images/start.png -------------------------------------------------------------------------------- /public/js/lib/leaflet-measure/images/start_@2X.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/leaflet-measure/images/start_@2X.png -------------------------------------------------------------------------------- /public/js/lib/leaflet-measure/images/trash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/leaflet-measure/images/trash.png -------------------------------------------------------------------------------- /public/js/lib/leaflet-measure/images/trash_@2X.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/leaflet-measure/images/trash_@2X.png -------------------------------------------------------------------------------- /public/js/lib/leaflet-plugins/GPX.Speed.js: -------------------------------------------------------------------------------- 1 | //#include 'GPX.js' 2 | 3 | (function () { 4 | 5 | function d2h (d) { 6 | var hex = '0123456789ABCDEF'; 7 | var r = ''; 8 | d = Math.floor(d); 9 | while (d !== 0) { 10 | r = hex[d % 16] + r; 11 | d = Math.floor(d / 16); 12 | } 13 | while (r.length < 2) r = '0' + r; 14 | return r; 15 | } 16 | 17 | function gradient (color) { 18 | // First arc (0, PI) in HSV colorspace 19 | function f2h (d) { return d2h(256 * d); } 20 | if (color < 0) 21 | return '#FF0000'; 22 | else if (color < 1.0/3) 23 | return '#FF' + f2h(3 * color) + '00'; 24 | else if (color < 2.0/3) 25 | return '#' + f2h(2 - 3 * color) + 'FF00'; 26 | else if (color < 1) 27 | return '#00FF' + f2h(3 * color - 2); 28 | else 29 | return '#00FFFF'; 30 | } 31 | 32 | function gpx2time (s) { 33 | // 2011-09-24T12:07:53Z 34 | if (s.length !== 10 + 1 + 8 + 1) 35 | return new Date(); 36 | return new Date(s); 37 | } 38 | 39 | L.GPX.include({ 40 | options: { 41 | maxSpeed: 110, 42 | chunks: 200 43 | }, 44 | 45 | speedSplitEnable: function (options) { 46 | L.Util.setOptions(this, options); 47 | return this.on('addline', this.speed_split, this); 48 | }, 49 | 50 | speedSplitDisable: function () { 51 | return this.off('addline', this.speed_split, this); 52 | }, 53 | 54 | speed_split: function (e) { 55 | var l = e.line.pop(), ll = l.getLatLngs(); 56 | var chunk = Math.floor(ll.length / this.options.chunks); 57 | if (chunk < 3) chunk = 3; 58 | var p = null; 59 | for (var i = 0; i < ll.length; i += chunk) { 60 | var d = 0, t = null; 61 | if (i + chunk > ll.length) 62 | chunk = ll.length - i; 63 | for (var j = 0; j < chunk; j++) { 64 | if (p) d += p.distanceTo(ll[i+j]); 65 | p = ll[i + j]; 66 | if (!t) t = gpx2time(p.meta.time); 67 | } 68 | p = ll[i + chunk - 1]; 69 | t = (gpx2time(p.meta.time) - t) / (3600 * 1000); 70 | var speed = 0.001 * d / t; 71 | var color = gradient(speed / this.options.maxSpeed); 72 | var poly = new L.Polyline(ll.slice(i, i+chunk+1), {color: color, weight: 2, opacity: 1}); 73 | poly.bindPopup('Dist: ' + d.toFixed() + 'm; Speed: ' + speed.toFixed(2) + ' km/h'); 74 | e.line.push(poly); 75 | } 76 | } 77 | 78 | }); 79 | })(); 80 | -------------------------------------------------------------------------------- /public/js/lib/leaflet-plugins/Icon.Canvas.js: -------------------------------------------------------------------------------- 1 | L.Icon.Canvas = L.Icon.extend({ 2 | options: { 3 | iconSize: new L.Point(20, 20), // Have to be supplied 4 | /* 5 | iconAnchor: (Point) 6 | popupAnchor: (Point) 7 | */ 8 | className: 'leaflet-canvas-icon' 9 | }, 10 | 11 | createIcon: function () { 12 | var e = document.createElement('canvas'); 13 | this._setIconStyles(e, 'icon'); 14 | var s = this.options.iconSize; 15 | e.width = s.x; 16 | e.height = s.y; 17 | this.draw(e.getContext('2d'), s.x, s.y); 18 | return e; 19 | }, 20 | 21 | createShadow: function () { 22 | return null; 23 | } 24 | }); 25 | -------------------------------------------------------------------------------- /public/js/lib/leaflet-plugins/Layer.Deferred.js: -------------------------------------------------------------------------------- 1 | L.DeferredLayer = L.LayerGroup.extend({ 2 | options: { 3 | js: [], 4 | init: null 5 | }, 6 | 7 | _script_cache: {}, 8 | 9 | initialize: function (options) { 10 | L.Util.setOptions(this, options); 11 | L.LayerGroup.prototype.initialize.apply(this); 12 | this._loaded = false; 13 | }, 14 | 15 | onAdd: function (map) { 16 | L.LayerGroup.prototype.onAdd.apply(this, [map]); 17 | if (this._loaded) return; 18 | var loaded = function () { 19 | this._loaded = true; 20 | var l = this.options.init(); 21 | if (l) 22 | this.addLayer(l); 23 | }; 24 | this._loadScripts(this.options.js.reverse(), L.Util.bind(loaded, this)); 25 | }, 26 | 27 | _loadScripts: function (scripts, cb, args) { 28 | if (!scripts || scripts.length === 0) 29 | return cb(args); 30 | var _this = this, s = scripts.pop(), c; 31 | c = this._script_cache[s]; 32 | if (c === undefined) { 33 | c = {url: s, wait: []}; 34 | var script = document.createElement('script'); 35 | script.src = s; 36 | script.type = 'text/javascript'; 37 | script.onload = function () { 38 | c.e.readyState = 'completed'; 39 | var i = 0; 40 | for (i = 0; i < c.wait.length; i++) 41 | c.wait[i](); 42 | }; 43 | c.e = script; 44 | document.getElementsByTagName('head')[0].appendChild(script); 45 | } 46 | function _cb () { _this._loadScripts(scripts, cb, args); } 47 | c.wait.push(_cb); 48 | if (c.e.readyState === 'completed') 49 | _cb(); 50 | this._script_cache[s] = c; 51 | } 52 | }); 53 | -------------------------------------------------------------------------------- /public/js/lib/leaflet-plugins/Layers.Load.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Add async initialization of layers to L.Control.Layers 3 | */ 4 | L.Control.Layers.include({ 5 | _loadScripts: function (scripts, cb, args) { 6 | if (!scripts || scripts.length === 0) 7 | return cb(args); 8 | var _this = this, s = scripts.pop(), c; 9 | c = L.Control.Layers._script_cache[s]; 10 | if (c === undefined) { 11 | c = {url: s, wait: []}; 12 | var script = document.createElement('script'); 13 | script.src = s; 14 | script.type = 'text/javascript'; 15 | script.onload = function () { 16 | var i = 0; 17 | for (i = 0; i < c.wait.length; i++) 18 | c.wait[i](); 19 | }; 20 | c.e = script; 21 | document.getElementsByTagName('head')[0].appendChild(script); 22 | } 23 | function _cb () { _this._loadScripts(scripts, cb, args); } 24 | c.wait.push(_cb); 25 | if (c.e.readyState === 'completed') 26 | _cb(); 27 | L.Control.Layers._script_cache[s] = c; 28 | }, 29 | 30 | addLayerDef: function (name, def) { 31 | if (this._layer_defs === undefined) 32 | this._layer_defs = {}; 33 | this._layer_defs[name] = def; 34 | }, 35 | 36 | addLayerDefs: function (defs) { 37 | if (this._layer_defs === undefined) 38 | this._layer_defs = {}; 39 | L.Util.extend(this._layer_defs, defs); 40 | }, 41 | 42 | loadLayer: function (name, deflt) { 43 | var _this = this, l = this._layer_defs[name]; 44 | l['default'] = deflt; 45 | this._loadScripts(l.js.reverse(), function (l) {_this._loadLayer(l);}, l); 46 | }, 47 | 48 | _loadLayer: function (l) { 49 | var x = l.init(); 50 | if (l['default'] && this._map) 51 | this._map.addLayer(x); 52 | if (!l.overlay) 53 | this.addBaseLayer(x, l.name); 54 | else 55 | this.addOverlay(x, l.name); 56 | } 57 | }); 58 | 59 | L.Control.Layers._script_cache = {}; 60 | -------------------------------------------------------------------------------- /public/js/lib/leaflet-plugins/Marker.Rotate.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Based on comments by @runanet and @coomsie 3 | * https://github.com/CloudMade/Leaflet/issues/386 4 | * 5 | * Wrapping function is needed to preserve L.Marker.update function 6 | */ 7 | (function () { 8 | var _old__setPos = L.Marker.prototype._setPos; 9 | L.Marker.include({ 10 | _updateImg: function (i, a, s) { 11 | a = L.point(s).divideBy(2)._subtract(L.point(a)); 12 | var transform = ''; 13 | transform += ' translate(' + -a.x + 'px, ' + -a.y + 'px)'; 14 | transform += ' rotate(' + this.options.iconAngle + 'deg)'; 15 | transform += ' translate(' + a.x + 'px, ' + a.y + 'px)'; 16 | i.style[L.DomUtil.TRANSFORM] += transform; 17 | i.style[L.DomUtil.TRANSFORM + 'Origin'] = '50% 50%'; 18 | }, 19 | 20 | _getShortestEndDegree: function (startDegrees, endDegrees) { 21 | var turnAngle = Math.abs(endDegrees - startDegrees); 22 | var turnAnglePositive = (endDegrees - startDegrees) >= 0; 23 | if (turnAngle <= 180) return endDegrees; 24 | var result = startDegrees + (360 - turnAngle) * (turnAnglePositive ? -1 : 1); 25 | return result; 26 | }, 27 | 28 | setIconAngle: function (iconAngle) { 29 | // find shortest angle to turn over 30 | this.options.iconAngle = this._getShortestEndDegree(this.options.iconAngle || 0, iconAngle); 31 | if (this._map) 32 | this.update(); 33 | }, 34 | 35 | _setPos: function (pos) { 36 | if (this._icon) 37 | this._icon.style[L.DomUtil.TRANSFORM] = ''; 38 | if (this._shadow) 39 | this._shadow.style[L.DomUtil.TRANSFORM] = ''; 40 | 41 | _old__setPos.apply(this,[pos]); 42 | 43 | if (this.options.iconAngle) { 44 | var defaultIcon = new L.Icon.Default(); 45 | var a = this.options.icon.options.iconAnchor || defaultIcon.options.iconAnchor; 46 | var s = this.options.icon.options.iconSize || defaultIcon.options.iconSize; 47 | var i; 48 | if (this._icon) { 49 | i = this._icon; 50 | this._updateImg(i, a, s); 51 | } 52 | if (this._shadow) { 53 | if (this.options.icon.options.shadowAnchor) 54 | a = this.options.icon.options.shadowAnchor; 55 | s = this.options.icon.options.shadowSize; 56 | i = this._shadow; 57 | this._updateImg(i, a, s); 58 | } 59 | } 60 | } 61 | }); 62 | }()); 63 | -------------------------------------------------------------------------------- /public/js/lib/leaflet-plugins/Marker.Text.js: -------------------------------------------------------------------------------- 1 | L.Icon.Text = L.Icon.extend({ 2 | initialize: function (text, options) { 3 | this._text = text; 4 | L.Icon.prototype.initialize.apply(this, [options]); 5 | }, 6 | 7 | createIcon: function () { 8 | var el = document.createElement('div'); 9 | el.appendChild(document.createTextNode(this._text)); 10 | this._setIconStyles(el, 'icon'); 11 | el.style.textShadow = '2px 2px 2px #fff'; 12 | return el; 13 | }, 14 | 15 | createShadow: function () { return null; } 16 | 17 | }); 18 | 19 | L.Marker.Text = L.Marker.extend({ 20 | initialize: function (latlng, text, options) { 21 | L.Marker.prototype.initialize.apply(this, [latlng, options]); 22 | this._fakeicon = new L.Icon.Text(text); 23 | }, 24 | 25 | _initIcon: function () { 26 | L.Marker.prototype._initIcon.apply(this); 27 | 28 | var i = this._icon, s = this._shadow, obj = this.options.icon; 29 | this._icon = this._shadow = null; 30 | 31 | this.options.icon = this._fakeicon; 32 | L.Marker.prototype._initIcon.apply(this); 33 | this.options.icon = obj; 34 | 35 | if (s) { 36 | s.parentNode.removeChild(s); 37 | this._icon.appendChild(s); 38 | } 39 | 40 | i.parentNode.removeChild(i); 41 | this._icon.appendChild(i); 42 | 43 | var w = this._icon.clientWidth, h = this._icon.clientHeight; 44 | this._icon.style.marginLeft = -w / 2 + 'px'; 45 | //this._icon.style.backgroundColor = "red"; 46 | var off = new L.Point(w/2, 0); 47 | if (L.Browser.webkit) off.y = -h; 48 | L.DomUtil.setPosition(i, off); 49 | if (s) L.DomUtil.setPosition(s, off); 50 | } 51 | }); 52 | -------------------------------------------------------------------------------- /public/js/lib/leaflet-plugins/Permalink.Layer.js: -------------------------------------------------------------------------------- 1 | //#include "Permalink.js 2 | 3 | L.Control.Permalink.include({ 4 | /* 5 | options: { 6 | useMarker: true, 7 | markerOptions: {} 8 | }, 9 | */ 10 | 11 | initialize_layer: function () { 12 | this.on('update', this._set_layer, this); 13 | this.on('add', this._onadd_layer, this); 14 | }, 15 | 16 | _onadd_layer: function () { 17 | this._map.on('layeradd', this._update_layer, this); 18 | this._map.on('layerremove', this._update_layer, this); 19 | this._update_layer(); 20 | }, 21 | 22 | _update_layer: function () { 23 | if (!this.options.layers) return; 24 | var layer = this.options.layers.currentBaseLayer(); 25 | if (layer) 26 | this._update({layer: layer.name}); 27 | }, 28 | 29 | _set_layer: function (e) { 30 | var p = e.params; 31 | if (!this.options.layers || !p.layer) return; 32 | this.options.layers.chooseBaseLayer(p.layer); 33 | } 34 | }); 35 | 36 | L.Control.Layers.include({ 37 | chooseBaseLayer: function (name) { 38 | var layer, obj; 39 | for (var i in this._layers) { 40 | if (!this._layers.hasOwnProperty(i)) 41 | continue; 42 | obj = this._layers[i]; 43 | if (!obj.overlay && obj.name === name) 44 | layer = obj.layer; 45 | } 46 | if (!layer || this._map.hasLayer(layer)) 47 | return; 48 | 49 | for (var j in this._layers) { 50 | if (!this._layers.hasOwnProperty(j)) 51 | continue; 52 | obj = this._layers[j]; 53 | if (!obj.overlay && this._map.hasLayer(obj.layer)) 54 | this._map.removeLayer(obj.layer); 55 | } 56 | this._map.addLayer(layer); 57 | this._update(); 58 | }, 59 | 60 | currentBaseLayer: function () { 61 | for (var i in this._layers) { 62 | if (!this._layers.hasOwnProperty(i)) 63 | continue; 64 | var obj = this._layers[i]; 65 | if (obj.overlay) continue; 66 | if (!obj.overlay && this._map.hasLayer(obj.layer)) 67 | return obj; 68 | } 69 | } 70 | }); 71 | 72 | -------------------------------------------------------------------------------- /public/js/lib/leaflet-plugins/Permalink.Line.js: -------------------------------------------------------------------------------- 1 | //#include "Permalink.js 2 | 3 | L.Control.Permalink.include({ 4 | /* 5 | options: { 6 | line: null 7 | }, 8 | */ 9 | 10 | initialize_line: function () { 11 | this.on('update', this._set_line, this); 12 | this.on('add', this._onadd_line, this); 13 | }, 14 | 15 | _onadd_line: function () { 16 | if (!this.options.line) return; 17 | this.options.line.on('edit', this._update_line, this); 18 | this._update_line(); 19 | }, 20 | 21 | _update_line: function () { 22 | if (!this.options.line) return; 23 | var line = this.options.line; 24 | if (!line) return; 25 | var text = [], coords = line.getLatLngs(); 26 | if (!coords.length) 27 | return this._update({line: null}); 28 | for (var i in coords) 29 | text.push(coords[i].lat.toFixed(4) + ',' + coords[i].lng.toFixed(4)); 30 | this._update({line: text.join(';')}); 31 | }, 32 | 33 | _set_line: function (e) { 34 | var p = e.params, l = this.options.line; 35 | if (!l || !p.line) return; 36 | var coords = [], text = p.line.split(';'); 37 | for (var i in text) { 38 | var ll = text[i].split(','); 39 | if (ll.length !== 2) continue; 40 | coords.push(new L.LatLng(ll[0], ll[1])); 41 | } 42 | if (!coords.length) return; 43 | l.setLatLngs(coords); 44 | if (!this._map.hasLayer(l)) 45 | this._map.addLayer(l); 46 | } 47 | }); 48 | -------------------------------------------------------------------------------- /public/js/lib/leaflet-plugins/Permalink.Marker.js: -------------------------------------------------------------------------------- 1 | //#include "Permalink.js 2 | 3 | L.Control.Permalink.include({ 4 | /* 5 | options: { 6 | useMarker: true, 7 | markerOptions: {} 8 | }, 9 | */ 10 | 11 | initialize_marker: function () { 12 | this.on('update', this._set_marker, this); 13 | }, 14 | 15 | _set_marker: function (e) { 16 | var p = e.params; 17 | //if (!this.options.useMarker) return; 18 | if (this._marker) return; 19 | if (p.marker !== 1) return; 20 | if (p.mlat !== undefined && p.mlon !== undefined) 21 | return this._update({mlat: null, mlon: null, 22 | lat: p.mlat, lon: p.mlon, marker: 1}); 23 | this._marker = new L.Marker(new L.LatLng(p.lat, p.lon), 24 | this.options.markerOptions); 25 | this._marker.bindPopup('' + this.options.text + ''); 26 | this._map.addLayer(this._marker); 27 | this._update({marker: null}); 28 | } 29 | }); 30 | -------------------------------------------------------------------------------- /public/js/lib/leaflet-plugins/Permalink.Overlay.js: -------------------------------------------------------------------------------- 1 | //#include "Permalink.js 2 | 3 | L.Control.Permalink.include({ 4 | 5 | initialize_overlay: function () { 6 | this.on('update', this._set_overlays, this); 7 | this.on('add', this._onadd_overlay, this); 8 | }, 9 | 10 | _onadd_overlay: function () { 11 | this._map.on('overlayadd', this._update_overlay, this); 12 | this._map.on('overlayremove', this._update_overlay, this); 13 | this._update_overlay(); 14 | }, 15 | 16 | _update_overlay: function () { 17 | if (!this.options.layers) return; 18 | var overlayflags = this.options.layers.overlayFlags(); 19 | if (overlayflags && overlayflags !== '') { 20 | this._update({overlays: overlayflags}); 21 | } 22 | }, 23 | 24 | _set_overlays: function (e) { 25 | var p = e.params; 26 | if (!this.options.layers || !p.overlays) return; 27 | this.options.layers.setOverlays(p.overlays); 28 | } 29 | }); 30 | 31 | L.Control.Layers.include({ 32 | setOverlays: function (overlayflags) { 33 | var obj, idx=0; 34 | for (var i in this._layers) { 35 | if (!this._layers.hasOwnProperty(i)) continue; 36 | obj = this._layers[i]; 37 | if (obj.overlay) { 38 | // visible if not specified or flag==T 39 | var visible = (idx >= overlayflags.length || overlayflags[idx] === 'T'); 40 | idx++; 41 | if (!visible && this._map.hasLayer(obj.layer)) { 42 | this._map.removeLayer(obj.layer); 43 | } else if (visible && !this._map.hasLayer(obj.layer)) { 44 | this._map.addLayer(obj.layer); 45 | } 46 | } 47 | } 48 | }, 49 | 50 | overlayFlags: function () { 51 | var flags = ''; 52 | for (var i in this._layers) { 53 | if (!this._layers.hasOwnProperty(i)) 54 | continue; 55 | var obj = this._layers[i]; 56 | if (!obj.overlay) continue; 57 | if (obj.overlay) { 58 | if (this._map.hasLayer(obj.layer)) { 59 | flags += 'T'; 60 | } else { 61 | flags += 'F'; 62 | } 63 | } 64 | } 65 | return flags; 66 | } 67 | }); -------------------------------------------------------------------------------- /public/js/lib/leaflet-side-by-side/.npmignore: -------------------------------------------------------------------------------- 1 | leaflet-side-by-side.js 2 | leaflet-side-by-side.min.js 3 | screencast.gif 4 | -------------------------------------------------------------------------------- /public/js/lib/leaflet-side-by-side/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | This project adheres to [Semantic Versioning](http://semver.org/). 5 | 6 | ## Unreleased 7 | 8 | ## [v2.0.0] - 2015-12-08 9 | 10 | - ADDED: Add `setLeftLayers()` and `setRightLayers()` methods 11 | - ADDED: `options.padding` 12 | - ADDED: `getPosition()` returns the x coordinate (relative to the map container) of the divider 13 | - FIXED: **[BREAKING]** Export factory function on `L.control` not `L.Control` 14 | - FIXED: Slider drag was not working on touch devices 15 | 16 | ## [v1.1.1] - 2015-12-03 17 | 18 | - FIXED: fix package.json settings for npm distribution 19 | 20 | ## [v1.1.0] - 2015-12-03 21 | 22 | - ADDED: Events 23 | - FIXED: Fix initial divider position in Firefox, should start in middle of map 24 | 25 | ## v1.0.2 - 2015-12-02 26 | 27 | Initial release 28 | 29 | [Unreleased]: https://github.com/digidem/leaflet-side-by-side/compare/v2.0.0...HEAD 30 | [Unreleased]: https://github.com/digidem/leaflet-side-by-side/compare/v1.1.1...v2.0.0 31 | [v1.1.1]: https://github.com/digidem/leaflet-side-by-side/compare/v1.1.0...v1.1.1 32 | [v1.1.0]: https://github.com/digidem/leaflet-side-by-side/compare/v1.0.2...v1.1.0 33 | -------------------------------------------------------------------------------- /public/js/lib/leaflet-side-by-side/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Gregor MacLennan 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a 4 | copy of this software and associated documentation files (the "Software"), 5 | to deal in the Software without restriction, including without limitation 6 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | and/or sell copies of the Software, and to permit persons to whom the 8 | Software is furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | DEALINGS IN THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /public/js/lib/leaflet-side-by-side/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Leaflet Side-by-side 7 | 8 | 9 | 10 | 22 | 23 | 24 | 25 |
    26 | 27 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /public/js/lib/leaflet-side-by-side/layout.css: -------------------------------------------------------------------------------- 1 | .leaflet-sbs-range { 2 | position: absolute; 3 | top: 50%; 4 | width: 100%; 5 | z-index: 999; 6 | } 7 | .leaflet-sbs-divider { 8 | position: absolute; 9 | top: 0; 10 | bottom: 0; 11 | left: 50%; 12 | margin-left: -2px; 13 | width: 4px; 14 | background-color: #fff; 15 | pointer-events: none; 16 | z-index: 999; 17 | } 18 | -------------------------------------------------------------------------------- /public/js/lib/leaflet-side-by-side/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "leaflet-side-by-side", 3 | "version": "2.0.0", 4 | "description": "Compare two Leaflet layers side by side", 5 | "main": "index.js", 6 | "browserify": { 7 | "transform": [ 8 | "css-img-datauri-stream", 9 | "cssify", 10 | "browserify-shim" 11 | ] 12 | }, 13 | "browserify-shim": { 14 | "leaflet": "global:L" 15 | }, 16 | "scripts": { 17 | "build": "browserify index.js > leaflet-side-by-side.js", 18 | "postbuild": "uglifyjs leaflet-side-by-side.js -cm -o leaflet-side-by-side.min.js", 19 | "preversion": "npm test && npm run build", 20 | "lint": "standard index.js", 21 | "start": "budo index.js:leaflet-side-by-side.js --live", 22 | "test": "npm run lint" 23 | }, 24 | "keywords": [ 25 | "leaflet" 26 | ], 27 | "author": "Gregor MacLennan / Digital Democracy", 28 | "license": "MIT", 29 | "devDependencies": { 30 | "browserify": "^12.0.1", 31 | "budo": "^7.0.0", 32 | "standard": "^5.4.1", 33 | "uglify-js": "^2.6.1" 34 | }, 35 | "dependencies": { 36 | "browserify-shim": "^3.8.11", 37 | "css-img-datauri-stream": "^0.1.5", 38 | "cssify": "^0.8.0", 39 | "leaflet": "^0.7.7" 40 | }, 41 | "repository": { 42 | "type": "git", 43 | "url": "git+https://github.com/digidem/leaflet-side-by-side.git" 44 | }, 45 | "bugs": { 46 | "url": "https://github.com/digidem/leaflet-side-by-side/issues" 47 | }, 48 | "homepage": "https://github.com/digidem/leaflet-side-by-side#readme" 49 | } 50 | -------------------------------------------------------------------------------- /public/js/lib/leaflet-side-by-side/range-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/leaflet-side-by-side/range-icon.png -------------------------------------------------------------------------------- /public/js/lib/leaflet-side-by-side/screencast.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/leaflet-side-by-side/screencast.gif -------------------------------------------------------------------------------- /public/js/lib/leaflet.locatecontrol/L.Control.Locate.css: -------------------------------------------------------------------------------- 1 | /* Compatible with Leaflet 0.7 */ 2 | .leaflet-control-locate a { 3 | font-size: 1.4em; 4 | color: #444; 5 | cursor: pointer; 6 | } 7 | .leaflet-control-locate.active a { 8 | color: #2074b6; 9 | } 10 | .leaflet-control-locate.active.following a { 11 | color: #fc8428; 12 | } 13 | 14 | .leaflet-touch .leaflet-bar .leaflet-locate-text-active { 15 | width: 100%; 16 | max-width: 200px; 17 | text-overflow: ellipsis; 18 | white-space: nowrap; 19 | overflow: hidden; 20 | padding: 0 10px; 21 | } 22 | .leaflet-touch .leaflet-bar .leaflet-locate-text-active .leaflet-locate-icon { 23 | padding: 0 5px 0 0; 24 | } 25 | 26 | .leaflet-control-locate-location circle { 27 | animation: leaflet-control-locate-throb 4s ease infinite; 28 | } 29 | 30 | @keyframes leaflet-control-locate-throb { 31 | 0% { 32 | stroke-width: 1; 33 | } 34 | 50% { 35 | stroke-width: 3; 36 | transform: scale(0.8, 0.8); 37 | } 38 | 100% { 39 | stroke-width: 1; 40 | } 41 | } 42 | 43 | /*# sourceMappingURL=L.Control.Locate.css.map */ 44 | -------------------------------------------------------------------------------- /public/js/lib/leaflet.tilelayer.wmts/leaflet.tilelayer.wmts.src.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | L.TileLayer.WMTS = L.TileLayer.extend({ 5 | defaultWmtsParams: { 6 | service: "WMTS", 7 | request: "GetTile", 8 | version: "1.0.0", 9 | layer: "", 10 | style: "default", 11 | tileMatrixSet: "", 12 | format: "image/jpeg", 13 | }, 14 | initialize: function (url, options) { 15 | this._url = url; 16 | const wmtsParams = L.extend({}, this.defaultWmtsParams); 17 | // all keys that are not TileLayer options go to WMS params 18 | for (const i in options) { 19 | if (!(i in this.options)) { 20 | wmtsParams[i] = options[i]; 21 | } 22 | } 23 | options = L.setOptions(this, options); 24 | const realRetina = options.detectRetina && retina ? 2 : 1; 25 | const tileSize = this.getTileSize(); 26 | wmtsParams.width = tileSize.x * realRetina; 27 | wmtsParams.height = tileSize.y * realRetina; 28 | this.wmtsParams = wmtsParams; 29 | }, 30 | getTileUrl: function (coords) { 31 | const zoom = this._tileZoom.toString(); 32 | if (this.wmtsParams.tileMatrixTransform) { 33 | const s = Function('"use strict";return (' + this.wmtsParams.tileMatrixTransform + ')')(); 34 | this.wmtsParams.tileMatrix = s(zoom) 35 | } else { 36 | this.wmtsParams.tileMatrix = zoom; 37 | } 38 | const url = L.Util.template(this._url, {s: this._getSubdomain(coords)}); 39 | const params = {...this.wmtsParams, tileRow: coords.y, tileCol: coords.x}; 40 | return url + L.Util.getParamString(params); 41 | }, 42 | setParams: function (params, noRedraw) { 43 | L.extend(this.wmtsParams, params); 44 | if (!noRedraw) { 45 | this.redraw(); 46 | } 47 | return this; 48 | }, 49 | }); 50 | L.tileLayer.wmts = function (url, options) { 51 | return new L.TileLayer.WMTS(url, options); 52 | }; 53 | }()); 54 | -------------------------------------------------------------------------------- /public/js/lib/leaflet.toolbar/leaflet.toolbar.css: -------------------------------------------------------------------------------- 1 | .leaflet-toolbar-0{list-style:none;padding-left:0;border:2px solid rgba(0,0,0,.2);border-bottom-left-radius:4px;border-bottom-right-radius:4px;border-top-left-radius:4px;border-top-right-radius:4px}.leaflet-toolbar-0>li{position:relative}.leaflet-toolbar-0>li>.leaflet-toolbar-icon{display:block;width:30px;height:30px;line-height:30px;margin-right:0;padding-right:0;border-right:0;text-align:center;text-decoration:none;background-color:#fff}.leaflet-toolbar-0>li>.leaflet-toolbar-icon:hover{background-color:#f4f4f4}.leaflet-toolbar-0 .leaflet-toolbar-1{display:none;list-style:none}.leaflet-toolbar-tip-container{margin:0 auto;margin-top:-16px;height:16px;position:relative;overflow:hidden}.leaflet-toolbar-tip{width:16px;height:16px;margin:-8px auto 0;background-color:#fff;background-clip:content-box;border:2px solid rgba(0,0,0,.2);border-bottom-left-radius:4px;border-bottom-right-radius:4px;border-top-left-radius:4px;border-top-right-radius:4px;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.leaflet-control-toolbar>li>.leaflet-toolbar-icon{border-bottom:1px solid #ccc}.leaflet-control-toolbar>li:first-child>.leaflet-toolbar-icon{border-top-left-radius:4px;border-top-right-radius:4px}.leaflet-control-toolbar>li:last-child>.leaflet-toolbar-icon{border-bottom-left-radius:4px;border-bottom-right-radius:4px;border-bottom-width:0}.leaflet-control-toolbar .leaflet-toolbar-1{margin:0;padding:0;position:absolute;left:30px;top:0;white-space:nowrap;height:30px}.leaflet-control-toolbar .leaflet-toolbar-1>li{display:inline-block}.leaflet-control-toolbar .leaflet-toolbar-1>li>.leaflet-toolbar-icon{display:block;background-color:#919187;border-left:1px solid #aaa;color:#fff;font:11px/19px "Helvetica Neue",Arial,Helvetica,sans-serif;line-height:30px;text-decoration:none;padding-left:10px;padding-right:10px;height:30px}.leaflet-control-toolbar .leaflet-toolbar-1>li>.leaflet-toolbar-icon:hover{background-color:#a0a098}.leaflet-control-toolbar .leaflet-toolbar-1>li:last-child>.leaflet-toolbar-icon{border-top-right-radius:4px;border-bottom-right-radius:4px}.leaflet-popup-toolbar{position:relative;box-sizing:content-box}.leaflet-popup-toolbar>li{float:left}.leaflet-popup-toolbar>li>.leaflet-toolbar-icon{border-right:1px solid #ccc}.leaflet-popup-toolbar>li:first-child>.leaflet-toolbar-icon{border-top-left-radius:4px;border-bottom-left-radius:4px}.leaflet-popup-toolbar>li:last-child>.leaflet-toolbar-icon{border-top-right-radius:4px;border-bottom-right-radius:4px;border-bottom-width:0;border-right:none}.leaflet-popup-toolbar .leaflet-toolbar-1{position:absolute;top:30px;left:0;padding-left:0}.leaflet-popup-toolbar .leaflet-toolbar-1>li>.leaflet-toolbar-icon{position:relative;float:left;width:30px;height:30px} -------------------------------------------------------------------------------- /public/js/lib/leaflet/images/layers-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/leaflet/images/layers-2x.png -------------------------------------------------------------------------------- /public/js/lib/leaflet/images/layers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/leaflet/images/layers.png -------------------------------------------------------------------------------- /public/js/lib/leaflet/images/marker-icon-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/leaflet/images/marker-icon-2x.png -------------------------------------------------------------------------------- /public/js/lib/leaflet/images/marker-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/leaflet/images/marker-icon.png -------------------------------------------------------------------------------- /public/js/lib/leaflet/images/marker-shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/public/js/lib/leaflet/images/marker-shadow.png -------------------------------------------------------------------------------- /public/js/lib/snackbarjs/snackbar.min.css: -------------------------------------------------------------------------------- 1 | #snackbar-container{position:fixed;left:20px;bottom:0;z-index:99999}.snackbar{overflow:hidden;clear:both;min-width:288px;max-width:568px;cursor:pointer;opacity:0}.snackbar.snackbar-opened{height:auto;opacity:1}@media (max-width:767px){#snackbar-container{left:0!important;right:0;width:100%}#snackbar-container .snackbar{min-width:100%}#snackbar-container [class="snackbar snackbar-opened"]~.snackbar.toast{margin-top:20px}#snackbar-container [class="snackbar snackbar-opened"]{border-radius:0;margin-bottom:0}} -------------------------------------------------------------------------------- /public/less/styles.default.less: -------------------------------------------------------------------------------- 1 | @import "styles"; 2 | -------------------------------------------------------------------------------- /public/templates/standard/blank.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 24 | 25 |
    26 |
    27 |
    28 |
    29 |
    30 |
    31 |
    32 |
    33 | -------------------------------------------------------------------------------- /public/tmp/excel/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /public/tmp/print/json/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /public/tmp/print/pdf/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /public/tmp/print/png/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /public/tmp/stored_results/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /public/version.json: -------------------------------------------------------------------------------- 1 | {"version":"1.9.0","extensionsBuild":"1c9dc28ac76da9e005c1c7ea2f83d529"} -------------------------------------------------------------------------------- /scss/custom.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapcentia/vidi/28c4ee11dc9771376a6c4cc5979b3015c20f6632/scss/custom.scss -------------------------------------------------------------------------------- /scss/main.scss: -------------------------------------------------------------------------------- 1 | @use "../node_modules/react-widgets/scss/styles" with ( 2 | $input-height: 2em, 3 | 4 | $components: ( 5 | 'Listbox', 6 | 'DropdownList', 7 | 'Combobox', 8 | 'Multiselect', 9 | 'NumberPicker' 10 | ) 11 | ); 12 | 13 | // Custom.scss 14 | // Option B: Include parts of Bootstrap 15 | 16 | // 1. Include functions first (so you can manipulate colors, SVGs, calc, etc) 17 | @import "../node_modules/bootstrap/scss/functions"; 18 | 19 | // 2. Include any default variable overrides here 20 | $accordion-icon-active-color: #ffffff; 21 | @import "./custom"; 22 | 23 | // 5. Include remainder of required parts 24 | @import "../node_modules/bootstrap/scss/bootstrap"; 25 | 26 | // 8. Add additional custom code here 27 | @import "./styles"; 28 | @import "./themes"; 29 | 30 | 31 | ; 32 | -------------------------------------------------------------------------------- /scss/themes.scss: -------------------------------------------------------------------------------- 1 | [data-bs-theme="groent_torvet"] { 2 | @charset "UTF-8"; 3 | /* latin */ 4 | @font-face { 5 | font-family: 'Playfair Display'; 6 | font-style: normal; 7 | font-weight: 400 900; 8 | font-display: swap; 9 | src: url(https://fonts.gstatic.com/s/playfairdisplay/v37/nuFiD-vYSZviVYUb_rj3ij__anPXDTzYgA.woff2) format('woff2'); 10 | unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; 11 | } 12 | /* latin */ 13 | @font-face { 14 | font-family: 'Open Sans'; 15 | font-style: normal; 16 | font-weight: 300 800; 17 | font-stretch: 100%; 18 | font-display: swap; 19 | src: url(https://fonts.gstatic.com/s/opensans/v40/memvYaGs126MiZpBA-UvWbX2vVnXBbObj2OVTS-muw.woff2) format('woff2'); 20 | unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; 21 | } 22 | 23 | @font-face { 24 | font-family: "Italian Plate No4"; 25 | src: url("ItalianPlateNo4Expanded-Regular.otf") format("opentype"); 26 | } 27 | 28 | 29 | --bs-body-font-family: 'Playfair Display'; 30 | 31 | // Your custom variables 32 | $primary: #ff6633; 33 | // Then import Bootstrap’s main SCSS 34 | } 35 | -------------------------------------------------------------------------------- /test/README.md: -------------------------------------------------------------------------------- 1 | ## Builds 2 | 3 | https://travis-ci.org/sashuk/vidi 4 | 5 | ## Testing 6 | 7 | Right now there are no available tools for testing the offline mode with service workers (not supported by Puppeteer as well https://github.com/GoogleChrome/puppeteer/issues/2469), so some tests need to be implemented when it will become available. 8 | 9 | Following options do not work: 10 | - using `page.setOfflineMode(true)` 11 | - using the DevTools protocol, the `Network.emulateNetworkConditions({ offline: true })` 12 | - using the DevTools protocol, the `Network.requestServedFromCache()` 13 | - intercepting responses and checking if they were served from cache 14 | 15 | When offline application mode becomes available, following cases has to be processed: 16 | - how layer offline mode controls react to changes in application availability 17 | - how application loads assets in offline mode 18 | - editor detecting the offline mode state 19 | 20 | ## Sample configurations 21 | 22 | Some test cases require custom Vidi configuration files that are typically located in `/public/api/config`. Examples of these files can be found in `./config` folder. 23 | 24 | ## Testing environment 25 | 26 | The regression is tested using the TravisCI (https://travis-ci.org/sashuk/vidi). Most of the tests are using a Puppeteer to request the Vidi installations and perform specific actions (testing of the entire application stack from Vidi frontend, then Vidi backend, the GC2 API / WMS / etc.). Regression tests expect following deployments (configurations for these deployments are located in the `./test/config/regression`, the list of URLs is located `./test/helpers.js`, the configuration for Nginx reverse proxy is in the `./test/config/regression/nginx_config/nginx.conf`): 27 | - the regular Vidi installation with SSL enabled 28 | - the regular Vidi installation with SSL disabled 29 | - the embed module enabled Vidi installation 30 | - the latest Vidi codebase installation 31 | 32 | The `vidi.alexshumilov.ru` domain should be replaced with the domain of the new deployment everywhere. The Github hook for `develop` branch should be used to update and rebuild the regression deployments. The SSL for regression deployment should be enabled via Nginx (using Let's Encrypt, for example). -------------------------------------------------------------------------------- /test/api/static.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Testing static PNG API 3 | */ 4 | 5 | const { expect } = require(`chai`); 6 | const request = require(`request`); 7 | const helpers = require(`./../helpers`); 8 | 9 | describe('Static PNG API', () => { 10 | it('should generate PNG image according to provided filters', (done) => { 11 | let buff = new Buffer.from(JSON.stringify({ 12 | "test.city_center": { 13 | "match":"any", 14 | "columns":[{ 15 | "fieldname":"id", 16 | "expression":">", 17 | "value":"6", 18 | "restriction":false 19 | }] 20 | } 21 | })); 22 | 23 | const url = `${helpers.API_URL}/static/mydb/test?filter=${buff.toString('base64')}&width=600&height=600`; 24 | request({ 25 | method: `GET`, 26 | url 27 | }, (error, response, body) => { 28 | expect(response.statusCode).to.equal(200); 29 | expect(response.headers['content-type']).to.equal('image/png'); 30 | expect(parseInt(response.headers['content-length']) > 100000).to.be.true; 31 | done(); 32 | }); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /test/config/aleksandrshumilov/aleksandrshumilov.json: -------------------------------------------------------------------------------- 1 | { 2 | "brandName": "Test" 3 | } -------------------------------------------------------------------------------- /test/config/aleksandrshumilov/aleksandrshumilov_baselayers.json: -------------------------------------------------------------------------------- 1 | { 2 | "baseLayers": [ 3 | { 4 | "id": "osm", 5 | "name": "OSM" 6 | }, 7 | { 8 | "id": "public.test_poly", 9 | "name": "Polygon", 10 | "db": "aleksandrshumilov", 11 | "host": "https://gc2.mapcentia.com", 12 | "config": { 13 | "maxZoom": 21, 14 | "maxNativeZoom": 20, 15 | "attribution": "© Mapbox" 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /test/config/aleksandrshumilov/aleksandrshumilov_baselayers_with_GC2.json: -------------------------------------------------------------------------------- 1 | { 2 | "baseLayers": [ 3 | { 4 | "id": "osm", 5 | "name": "OSM" 6 | }, 7 | { 8 | "id": "public.test_poly", 9 | "name": "Polygon", 10 | "db": "aleksandrshumilov", 11 | "host": "https://gc2.mapcentia.com", 12 | "config": { 13 | "maxZoom": 21, 14 | "maxNativeZoom": 20, 15 | "attribution": "© Mapbox" 16 | } 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /test/config/aleksandrshumilov/aleksandrshumilov_baselayers_without_GC2.json: -------------------------------------------------------------------------------- 1 | { 2 | "baseLayers": [{ 3 | "id": "osm", 4 | "name": "OSM" 5 | }], 6 | "brandName": "Test", 7 | "aboutBox": "Test" 8 | } -------------------------------------------------------------------------------- /test/config/aleksandrshumilov/aleksandrshumilov_with_startup_modal.json: -------------------------------------------------------------------------------- 1 | { 2 | "brandName": "Test", 3 | "startUpModal": "

    Welcome to Vidi

    HTML markup is allowed in startup modal

    " 4 | } 5 | -------------------------------------------------------------------------------- /test/config/vidi.json: -------------------------------------------------------------------------------- 1 | { 2 | "brandName": "Test" 3 | } -------------------------------------------------------------------------------- /test/helpers.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Helper functions 3 | */ 4 | const sleepFunction = (ms) => { 5 | return new Promise(resolve => setTimeout(resolve, ms)); 6 | }; 7 | 8 | module.exports = { 9 | API_URL: `http://127.0.0.1:3000/api`, 10 | // Base instance URL 11 | PAGE_URL_BASE: `http://127.0.0.1:3000/`, 12 | // Vidi instance with default template 13 | PAGE_URL_DEFAULT: `https://vidi.swarm.gc2.io/app/aleksandrshumilov/public/#osm/13/39.2963/-6.8335/`, 14 | // Vidi instance that works with newest backend (swarm.gc2.io testing:aDvvi9802dmosd) 15 | PAGE_URL_LATEST_GC2: `https://vidi.swarm.gc2.io/app/testing/public/#osm/13/39.2963/-6.8335/`, 16 | // Vidi instance with default template without SSL 17 | PAGE_URL_DEFAULT_NO_SSL: `http://vidi.swarm.gc2.io/app/aleksandrshumilov/public/#osm/13/39.2963/-6.8335/`, 18 | // Vidi instance with embedded template 19 | PAGE_URL_EMBEDDED: `https://vidi.swarm.gc2.io/app/aleksandrshumilov/public/#osm/13/39.2963/-6.8335/`, 20 | PAGE_LOAD_TIMEOUT: 1000, 21 | EMULATED_SCREEN: { 22 | viewport: { 23 | width: 1920, 24 | height: 1080 25 | }, 26 | userAgent: 'Puppeteer' 27 | }, 28 | sleep: sleepFunction, 29 | duplicate: (target) => JSON.parse(JSON.stringify(target)), 30 | waitForPageToLoad: async (page) => { 31 | let loadedPage = new Promise((resolve, reject) => { 32 | page.on('console', async (msg) => { 33 | //console.log(msg.text()); 34 | if (msg.text().indexOf(`Vidi is now loaded`) !== -1) { 35 | await sleepFunction(1000); 36 | resolve(page); 37 | } else if (msg.text().indexOf(`Limit of connection check attempts exceeded`) !== -1) { 38 | reject(new Error(`Unable to load the page`)); 39 | } 40 | }); 41 | }); 42 | 43 | return await loadedPage; 44 | }, 45 | img: async (page, path = `./test.png`) => { 46 | await page.screenshot({ path }); 47 | } 48 | }; 49 | -------------------------------------------------------------------------------- /test/puppeteer/bootstrap.js: -------------------------------------------------------------------------------- 1 | const puppeteer = require("puppeteer"); 2 | const axios = require("axios"); 3 | const localforage = require("localforage"); 4 | const { expect } = require("chai"); 5 | const _ = require("lodash"); 6 | const globalVariables = _.pick(global, ["browser", "expect", "localforage"]); 7 | const helpers = require('../helpers'); 8 | 9 | // puppeteer options 10 | const opts = { 11 | headless: true, 12 | timeout: 10000, 13 | args: ["--no-sandbox"] 14 | }; 15 | 16 | // expose variables 17 | beforeEach(async () => { 18 | global.expect = expect; 19 | global.localforage = localforage; 20 | global.browser = await puppeteer.launch(opts); 21 | let response = await axios.get(`https://swarm.gc2.io/api/v2/keyvalue/demo`); 22 | response.data.data.map(item => { 23 | axios.delete(`http://swarm.gc2.io/api/v2/keyvalue/aleksandrshumilov/${item.key}`); 24 | }); 25 | }); 26 | 27 | // close browser and reset global variables 28 | afterEach(async () => { 29 | await browser.close(); 30 | 31 | global.browser = globalVariables.browser; 32 | global.localforage = globalVariables.localforage; 33 | global.expect = globalVariables.expect; 34 | }); 35 | -------------------------------------------------------------------------------- /test/puppeteer/layerTree/tableView.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Testing layerTree module 3 | */ 4 | 5 | const { expect } = require("chai"); 6 | const helpers = require("./../../helpers"); 7 | 8 | describe('Layer tree table view', () => { 9 | it(`should load data for vector layers`, async () => { 10 | let page = await browser.newPage(); 11 | await page.emulate(helpers.EMULATED_SCREEN); 12 | await page.goto(helpers.PAGE_URL_DEFAULT, { timeout: 0 }); 13 | page = await helpers.waitForPageToLoad(page); 14 | 15 | await page.evaluate(`$('#search-border').trigger('click')`); 16 | await helpers.sleep(500); 17 | await page.evaluate(`$('[href="#layer-content"]').trigger('click')`); 18 | await helpers.sleep(500); 19 | await page.evaluate(`$('[href="#collapseRHluYW1pYyBsb2FkIHRlc3Q"]').trigger('click')`); 20 | await page.evaluate(`$('[href="#collapseUHVibGljIGdyb3Vw"]').trigger('click')`); 21 | await helpers.sleep(500); 22 | await page.evaluate(`$('[data-gc2-layer-key="public.dynamicloadtest.the_geom"]').find('.js-layer-type-selector-vector').trigger('click')`); 23 | await page.evaluate(`$('[data-gc2-layer-key="public.test_line.the_geom"] input').first().trigger('click')`); 24 | await helpers.sleep(500); 25 | 26 | // Enabling table view for points layer 27 | await page.evaluate(`$('[data-gc2-layer-key="public.dynamicloadtest.the_geom"]').find('.js-toggle-table-view').trigger('click')`); 28 | await helpers.sleep(500); 29 | expect(await page.evaluate(`$('[data-gc2-layer-key="public.dynamicloadtest.the_geom"]').find('tbody').is(':visible')`)).to.be.true; 30 | expect(await page.evaluate(`$('[data-gc2-layer-key="public.dynamicloadtest.the_geom"]').find('tbody').find('tr').length`)).to.equal(8); 31 | 32 | // Enabling table view for lines layer 33 | await page.evaluate(`$('[data-gc2-layer-key="public.test_line.the_geom"]').find('.js-toggle-table-view').trigger('click')`); 34 | await helpers.sleep(500); 35 | expect(await page.evaluate(`$('[data-gc2-layer-key="public.test_line.the_geom"]').find('tbody').is(':visible')`)).to.be.true; 36 | expect(await page.evaluate(`$('[data-gc2-layer-key="public.test_line.the_geom"]').find('tbody').find('tr').length`) > 0).to.be.true; 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /test/puppeteer/print.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Testing printing capabilities 3 | */ 4 | 5 | const { expect } = require("chai"); 6 | const helpers = require("./../helpers"); 7 | 8 | describe("Print", () => { 9 | it("should be able to print page as PDF multiple times", async () => { 10 | let page = await browser.newPage(); 11 | await page.goto(`${helpers.PAGE_URL_DEFAULT}public.test_poly,v:public.test_line`); 12 | page = await helpers.waitForPageToLoad(page); 13 | 14 | await page.evaluate(`$('#search-border').trigger('click')`); 15 | await helpers.sleep(1000); 16 | await page.evaluate(`$('[href="#print-content"]').trigger('click')`); 17 | await helpers.sleep(1000); 18 | await page.evaluate(`$('#print-btn').trigger('click')`); 19 | await helpers.sleep(1000); 20 | await page.evaluate(`$('#start-print-btn').trigger('click')`); 21 | await helpers.sleep(20000); 22 | 23 | let disabled = await page.evaluate(`$('#get-print-fieldset').attr('disabled')`); 24 | let firstPDFLink = await page.evaluate(`$('#open-pdf').attr('href')`); 25 | 26 | expect(disabled === undefined || disabled === `undefined`).to.be.true; 27 | expect(firstPDFLink.indexOf(`.pdf`) !== -1).to.be.true; 28 | 29 | await helpers.sleep(1000); 30 | await page.evaluate(`$('[href="#baselayer-content"]').trigger('click')`); 31 | await helpers.sleep(1000); 32 | await page.evaluate(`$('[data-gc2-base-id="stamenTonerLite"] input').trigger('click')`); 33 | await helpers.sleep(1000); 34 | 35 | await page.evaluate(`$('[href="#print-content"]').trigger('click')`); 36 | await helpers.sleep(1000); 37 | await page.evaluate(`$('#start-print-btn').trigger('click')`); 38 | await helpers.sleep(20000); 39 | 40 | let secondPDFLink = await page.evaluate(`$('#open-pdf').attr('href')`); 41 | expect(firstPDFLink && secondPDFLink && (firstPDFLink !== secondPDFLink)).to.be.true; 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /tmp/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore --------------------------------------------------------------------------------