Initial commit - Typo3 11.5.41
470
typo3conf/ext/ods_osm/ChangeLog
Normal file
@@ -0,0 +1,470 @@
|
||||
2023-10-06 Alexander Bigga <alexander@bigga.de>
|
||||
* Remove support for TYPO3 10.4, support for 12.4 LTS
|
||||
* Make geojson properties configurable to show in popup
|
||||
* Update Openlayers to 8.1.0
|
||||
|
||||
2023-01-15 Alexander Bigga <alexander@bigga.de>
|
||||
* Fix missing TCA configuration of fe_groups and sys_category in TYPO3 10.4. Thanks to Dirk Wildt, verdigado eG.
|
||||
* Fix exception on loading plugin settings if tt_address is not installed
|
||||
* Update to Leaflet 1.9.3
|
||||
|
||||
2022-11-27 Alexander Bigga <alexander@bigga.de>
|
||||
* fix show_popup for click and hover with OpenLayers and Leaflet
|
||||
* Show map on EXT:calendarize event detail if location is geo referenced
|
||||
* Cleanup the code with typo3-rector for TYPO3 11 and PHP 8.1
|
||||
|
||||
2022-10-03 Alexander Bigga <alexander@bigga.de>
|
||||
* Update to OpenLayers 7.1.0
|
||||
* Update to Leaflet 1.9.1
|
||||
* Add fullscreen mode
|
||||
|
||||
2021-04-02 Alexander Bigga <alexander@bigga.de>
|
||||
* Update to Leaflet 1.7.1
|
||||
* Refactored coordinate picker wizard based on Leaflet now
|
||||
* Add new vector draw wizard based on Leaflet now
|
||||
* Fix some deprecation warnings
|
||||
* Fix bug due to removed, deprected code in TYPO3 10 (thanks to Sybille Peters, @sypets)
|
||||
|
||||
2021-02-13 Alexander Bigga <alexander@bigga.de>
|
||||
* Compatibility with TYPO3 10.4 LTS and TYPO3 9.5 LTS
|
||||
* Update list of initial layer records. All active records support HTTPS now.
|
||||
* Update: Documentation
|
||||
|
||||
2020-04-13 Alexander Bigga <alexander@bigga.de>
|
||||
* Compatibility TYPO3 9.5 LTS
|
||||
* Update: Documentation
|
||||
|
||||
2019-01-17 Robert Heel <typo3@bobosch.de>
|
||||
* Add: Italian translation (Thanks to Claudio Strizzolo)
|
||||
* Update: Documentation
|
||||
|
||||
2017-04-02 Robert Heel <typo3@bobosch.de>
|
||||
* Request #27: 8.x compatibility (Thanks to Thorben Nissen).
|
||||
|
||||
2017-03-21 Robert Heel <typo3@bobosch.de>
|
||||
* Bug #80038: Clustered marker categories are not activated by default (Thanks to Volker Burggräf).
|
||||
|
||||
2017-02-28 Robert Heel <typo3@bobosch.de>
|
||||
* Bug #80037: Table tx_odsosm_layer not recreated on update.
|
||||
* Bug #80038: Leaflet layer switcher closed even opened is selected.
|
||||
* Bugfix: Use layer tile protocol if set.
|
||||
|
||||
2017-02-23 Robert Heel <typo3@bobosch.de>
|
||||
* Bug #77684: Markers not shown when clustering is active.
|
||||
|
||||
2017-02-14 Robert Heel <typo3@bobosch.de>
|
||||
* Issue #26: Add minimum zoom option.
|
||||
* Feature #73131: https option for layer tiles.
|
||||
|
||||
2017-01-22 Robert Heel <typo3@bobosch.de>
|
||||
* Change #30: Increase size of tile_url field.
|
||||
|
||||
2017-01-14 Robert Heel <typo3@bobosch.de>
|
||||
* Bugfix #28: Initialize layers array in leaflet library.
|
||||
|
||||
2016-09-01 Robert Heel <typo3@bobosch.de>
|
||||
* Bufix: Mixed up lat and lon on static map.
|
||||
|
||||
2016-04-23 Robert Heel <typo3@bobosch.de>
|
||||
* Bufix: Ignore wrong TS marker entries.
|
||||
|
||||
2016-04-23 Robert Heel <typo3@bobosch.de>
|
||||
* Bugfix: Typo in locallang_db.
|
||||
* Add: Missing configuration examples in TS setup and TS constants.
|
||||
* Change: Convert manual to REST format.
|
||||
* Add: Define marker icon with TS TEXT object.
|
||||
* Change: Search current page for markers if no marker configured.
|
||||
|
||||
2016-04-15 Robert Heel <typo3@bobosch.de>
|
||||
* Bugfix: Using json_encode to encode all javascript parameters with floatval (issue with '.' and ',') or escaped strings.
|
||||
|
||||
2016-04-14 Robert Heel <typo3@bobosch.de>
|
||||
* Change: Centralize marker icon information.
|
||||
* Add: Define marker icon with TS IMAGE object.
|
||||
|
||||
2016-03-19 Robert Heel <typo3@bobosch.de>
|
||||
* Change: Transfered tt_address marker into extension "ods_osm_tt_address". Install it if you use tt_address records!
|
||||
* Add: Extension ods_osm_tt_address 2.0.0 for tt_address 2.x
|
||||
* Add: Extension ods_osm_tt_address 3.0.0 for tt_address 3.x
|
||||
* Add: Extension ods_osm_tt_cal 1.0.0 for cal 1.x
|
||||
|
||||
2016-03-17 Robert Heel <typo3@bobosch.de>
|
||||
* Feature #48742: Allow jQuery usage.
|
||||
|
||||
2016-03-15 Robert Heel <typo3@bobosch.de>
|
||||
* Change: Add php 5.4 compatibility to class.tx_odsosm_div.php (Thanks to Daniel Minder).
|
||||
* Change: The usage of $GLOBALS['TSFE']->JSeventFuncCalls is deprecated as of TYPO3 CMS 7. Use Javascript directly.
|
||||
|
||||
2016-03-13 Robert Heel <typo3@bobosch.de>
|
||||
* Update: Documentation.
|
||||
* Change: Remove unused "Visible in map" switch on tracks.
|
||||
|
||||
2016-03-11 Robert Heel <typo3@bobosch.de>
|
||||
* Bugfix: Correct mm relation for sys_category.
|
||||
* Bugfix: 'IN' instead of '=' in flexform.xml.
|
||||
* Bugfix: Color attribute in leaflet tracks.
|
||||
|
||||
2016-03-10 Robert Heel <typo3@bobosch.de>
|
||||
* Bugfix: Show tt_content lon and lat in coordinate picker.
|
||||
* Bugfix: TYPO3 7 compatibility for tracks.
|
||||
|
||||
2016-03-08 Robert Heel <typo3@bobosch.de>
|
||||
* Bugfix: Show tt_address records in sys_category.
|
||||
* Bugfix: Fix static functions.
|
||||
|
||||
2016-03-07 Robert Heel <typo3@bobosch.de>
|
||||
* Bug #21: Coordinatepicker Wizard error in TYPO3 6.2.
|
||||
|
||||
2016-03-01 Robert Heel <typo3@bobosch.de>
|
||||
* Bugfix: Compatibility to TYPO3 7 and tt_address 3.
|
||||
* Change: Use tt_address longitude and latitude (Import old data with update function).
|
||||
|
||||
2016-02-08 Robert Heel <typo3@bobosch.de>
|
||||
* Bugfix: Not possible to center a map via TS.
|
||||
|
||||
2016-01-10 Robert Heel <typo3@bobosch.de>
|
||||
* Change: Allow popup for all types on leaflet.
|
||||
|
||||
2016-01-09 Robert Heel <typo3@bobosch.de>
|
||||
* Feature #67722: Add marker clusterer to leaflet.
|
||||
* Change: New version of update script.
|
||||
* Change: Use leaflet geoJson object for vector elements.
|
||||
* Bugfix: Unsupported operand types in class.tx_odsosm_pi1.php on line 99
|
||||
|
||||
2015-12-14 Robert Heel <typo3@bobosch.de>
|
||||
* Bug #72208: Invalid argument supplied for foreach() in class.tx_odsosm_leaflet.php line 17
|
||||
|
||||
2015-06-12 dawnbreak
|
||||
* Change: Add scalebar to leaflet map.
|
||||
|
||||
2015-06-02 Robert Heel <typo3@bobosch.de>
|
||||
* Change: Allow different javascript calls for OpenLayers and Leaflet.
|
||||
|
||||
2015-06-02 dawnbreak
|
||||
* Update: leaflet-plugins to 1.3.3.
|
||||
* Bugfix: Bug with base layers and leaflet.
|
||||
|
||||
2015-02-08 Robert Heel <typo3@bobosch.de>
|
||||
* Update: geoPHP to version 1.0
|
||||
* Change: Include only used leaflet plugins.
|
||||
|
||||
2015-01-25 Klaus Weidenbach <Klaus.Weidenbach@gmx.net>
|
||||
* Add: KML support when using Leaflet library.
|
||||
|
||||
2015-01-11 Robert Heel <typo3@bobosch.de>
|
||||
* Bug #64119: Import ext_tables_static+adt.sql with update function.
|
||||
|
||||
2014-12-19 Robert Heel <typo3@bobosch.de>
|
||||
* Bug #63990: Replace mysql function with TYPO3 function.
|
||||
|
||||
2014-12-17 Robert Heel <typo3@bobosch.de>
|
||||
* Add: Option to show current (gps) position in leaflet.
|
||||
* Bugfix: Change links from toolserver.org to wmflabs.org.
|
||||
|
||||
2014-10-26 Robert Heel <typo3@bobosch.de>
|
||||
* Bug #62424: Add absRefPrefix to path (Thanks to Alexander Bigga).
|
||||
|
||||
2014-10-23 Robert Heel <typo3@bobosch.de>
|
||||
* Bug #62424: Set default image path in leaflet (Thanks to Michael Oehlhof).
|
||||
|
||||
2014-10-11 Robert Heel <typo3@bobosch.de>
|
||||
* Bugfix: Escape slash in javascript.
|
||||
|
||||
2014-10-10 Robert Heel <typo3@bobosch.de>
|
||||
* Add: Overlay layer "Stamen Terrain Labels" (http://maps.stamen.com/).
|
||||
|
||||
2014-08-18 Robert Heel <typo3@bobosch.de>
|
||||
* Bug #61011: Invalid argument supplied for foreach() in class.tx_odsosm_pi1.php on line 127
|
||||
|
||||
2014-08-03 Robert Heel <typo3@bobosch.de>
|
||||
* Change: Cleanup library classes.
|
||||
* Add: Library OpenLayers 3.
|
||||
|
||||
2014-08-01 Robert Heel <typo3@bobosch.de>
|
||||
* Update: OpenLayers to version 2.13.1
|
||||
* Add: Base layer "Stamen Toner" (http://maps.stamen.com/#toner/).
|
||||
* Add: Base layer "Stamen Watercolor" (http://maps.stamen.com/#watercolor/).
|
||||
* Add: Overlay layer "Public Transport Lines" (http://www.openptmap.org/).
|
||||
* Bugfix: Set maximum number of markers to 9999 (-1 don't work in TYPO3 6.2).
|
||||
* Bugfix: Parameter crossOriginKeword is needed by OpenLayers >2.11.
|
||||
* Bugfix: Use leaflet files from leaflet.com if configured.
|
||||
* Update: Documentation.
|
||||
* Update: Google maps to api v3.
|
||||
* Update: Bing maps with api key.
|
||||
|
||||
2014-07-30 Robert Heel <typo3@bobosch.de>
|
||||
* Bugfix: New static URL for mapnik.
|
||||
|
||||
2014-07-29 Robert Heel <typo3@bobosch.de>
|
||||
* Add: Overlay layer "Cycling routes" (http://cycling.waymarkedtrails.org/).
|
||||
* Bugfix: Coordinate selection wizard works now in TYPO3 6.2.
|
||||
* Change: Remove local layer scripts and only use javascript includes with special layers.
|
||||
|
||||
2014-07-08 Robert Heel <typo3@bobosch.de>
|
||||
* Bugfix: Use global var osm_x in JS (Thanks to FriesenKiwi).
|
||||
* Quality: typo3.org "DoubleQuoteUsageNotRequired" and "OpeningFunctionBraceKernighanRitchieBraceOnNewLine" changed.
|
||||
|
||||
2014-06-17 Robert Heel <typo3@bobosch.de>
|
||||
* Bugfix: Compatibility to TYPO3 6.2 (Thanks to Charles Brunet).
|
||||
* Bugfix: Show marker without groups again.
|
||||
* Bugfix: htmlSpecialChars = 1 in default typoscript to allow special characters in description.
|
||||
|
||||
2014-05-29 Robert Heel <typo3@bobosch.de>
|
||||
* Add: Icon groups in Leaflet layer switch.
|
||||
* Update: Leaflet to version 0.7.3.
|
||||
|
||||
2014-05-15 Robert Heel <typo3@bobosch.de>
|
||||
* Add: Config option for GeoNames username.
|
||||
|
||||
2014-02-19 Robert Heel <typo3@bobosch.de>
|
||||
* Add: Default seperator parameter to geonames and nominatim http_build_query.
|
||||
|
||||
2014-02-06 Robert Heel <typo3@bobosch.de>
|
||||
* Bugfix: SQL error: Unknown column 'region' in 'field list' (fe_users).
|
||||
|
||||
2014-02-03 Robert Heel <typo3@bobosch.de>
|
||||
* Add: Base layer "MapQuest Open Aerial" (http://www.mapquest.com/).
|
||||
* Add: Database column for attribution.
|
||||
* Change: Also use tile_url in OpenLayers.
|
||||
|
||||
2014-01-12 Robert Heel <typo3@bobosch.de>
|
||||
* Bug: Use default configuration if extension is not configured.
|
||||
|
||||
2014-01-04 Robert Heel <typo3@bobosch.de>
|
||||
* Add: Some debug messages.
|
||||
|
||||
2013-12-17 Robert Heel <typo3@bobosch.de>
|
||||
* Bug: Get map work again without layer switch.
|
||||
|
||||
2013-12-08 Robert Heel <typo3@bobosch.de>
|
||||
* Bug: Wrong german localisation of layer switch options.
|
||||
|
||||
2013-12-07 Robert Heel <typo3@bobosch.de>
|
||||
* Add: Plugin option to activate the layer switcher opened.
|
||||
* Add: Track option to change visiblity of tracks.
|
||||
* Bug: Don't delete bounding coordinates from track on save.
|
||||
|
||||
2013-10-28 Robert Heel <typo3@bobosch.de>
|
||||
* Add: Plugin option "Use this coordinates only if no marker exists".
|
||||
|
||||
2013-10-26 Robert Heel <typo3@bobosch.de>
|
||||
* Add: Plugin option "Show Popup Exclusive" to show only one popup at once (Thanks to Klaus).
|
||||
|
||||
2013-09-12 Robert Heel <typo3@bobosch.de>
|
||||
* Bug #50028: Enhanced geocache.
|
||||
|
||||
2013-08-24 Robert Heel <typo3@bobosch.de>
|
||||
* Add: ScaleLine Control to OpenLayers maps (Thanks to Klaus).
|
||||
* Add: Address search cache configuration.
|
||||
|
||||
2013-08-09 Robert Heel <typo3@bobosch.de>
|
||||
* Bug #49251: PHP Warning: Invalid argument supplied for foreach() in class.tx_odsosm_leaflet.php.
|
||||
* Add: State field in address search.
|
||||
* Bug #49959: Nominatim: Trying a bit harder to get coordinates for markers (Thanks to Christoph Holtermann).
|
||||
|
||||
2013-08-09 Robert Heel <typo3@bobosch.de>
|
||||
* Add: tx_odsosm_track and tx_odsosm_vector for Leaflet (Thanks to Niklas Olmes).
|
||||
|
||||
2013-06-23 Robert Heel <typo3@bobosch.de>
|
||||
* Change: Compatibility to TYPO3 LTS Version 4.5.
|
||||
* Feature #48803: Use address field for geocoding.
|
||||
|
||||
2013-06-05 Robert Heel <typo3@bobosch.de>
|
||||
* Bug #48797: Update user agent version.
|
||||
* Bug #48886: PHP Warning: Missing argument 3 for tx_odsosm_leaflet::getMarker().
|
||||
* Feature #48743: Mass geo-code tt_address records (Thanks to Christian Weiske).
|
||||
* Feature #48804: Show popup opened (Thanks to Christian Weiske).
|
||||
|
||||
2013-06-01 Robert Heel <typo3@bobosch.de>
|
||||
* Update: Leaflet to version 0.5.1.
|
||||
* Bug #48752: Custom marker in Leaflet (Thanks to Christian Weiske).
|
||||
* Bug #48745: Enable popups in Leaflet (Thanks to Christian Weiske).
|
||||
|
||||
2013-03-07 Robert Heel <typo3@bobosch.de>
|
||||
* Bug #46088: Replaced unsupported \TYPO3\CMS\Core\Utility.
|
||||
|
||||
2013-02-25 Robert Heel <typo3@bobosch.de>
|
||||
* Bug: Replaced deprecated method readLLXMLfile.
|
||||
* Bug #45730: No translated overlays from tt_address_group (Thanks to Klaus Weidenbach).
|
||||
|
||||
2012-08-06 Robert Heel <rheel@1drop.de>
|
||||
* Change: Change default setting to use local javascript.
|
||||
* Workaround: Use remote OpenLayers version 2.11 (gpx tracks don't work in 2.12).
|
||||
|
||||
2012-07-20 Robert Heel <rheel@1drop.de>
|
||||
* Bug #39087: Popup marker for leaflet library.
|
||||
|
||||
2012-06-25 Robert Heel <rheel@1drop.de>
|
||||
* Bugfix: Popup marker back again.
|
||||
* Add: Leaflet subdomains information.
|
||||
|
||||
2012-06-09 Robert Heel <rheel@1drop.de>
|
||||
* Add: Layerswitcher for leaflet library.
|
||||
* Change: Code cleanup.
|
||||
|
||||
2012-05-31 Robert Heel <rheel@1drop.de>
|
||||
* Add: Leaflet library (http://leaflet.cloudmade.com/) (optimized for mobile devices).
|
||||
* Add: TS option "library" with values "leaflet", "OpenLayers" and "static".
|
||||
* Change: Removed TS options "static" and "static_layer" (use library=static and layer=x).
|
||||
* Change: Extract all javascript generation code to class files.
|
||||
|
||||
2012-04-15 Robert Heel <rheel@1drop.de>
|
||||
* Change: Use geoPHP 0.8 for track file analysis.
|
||||
* Add: Support for GeoJSON, KML and WKT tracks.
|
||||
|
||||
2012-03-29 Robert Heel <rheel@1drop.de>
|
||||
* Add: Base layer "MapQuest" (http://www.mapquest.com/).
|
||||
* Add: Base layer "TransportMap".
|
||||
* Remove: Base layer "Osmarender".
|
||||
* Update: OpenLayers to version 2.11.
|
||||
* Update: OpenStreetMap.js.
|
||||
* Update: Database structure.
|
||||
|
||||
2011-12-20 Robert Heel <rheel@1drop.de>
|
||||
* Bugfix: Show Map wizard in Backend without default coordinates.
|
||||
|
||||
2011-05-16 Robert Heel <rheel@1drop.de>
|
||||
* Add: Choose Record with GET or POST parameter records=[TABLE]_[ID].
|
||||
* Add: Configurable default map position in BE.
|
||||
|
||||
2011-03-02 Robert Heel <rheel@1drop.de>
|
||||
* Add: GeoJSON vector elements (alpha).
|
||||
* Change: Disable compression of JS in BE/FE (don't work).
|
||||
|
||||
2011-01-04 Robert Heel <rheel@1drop.de>
|
||||
* Add: Base layer "MapSurfer.Net Road ", "MapSurfer.Net Topographic", Overlay layer "MapSurfer.Net Hybrid" (http://www.mapsurfer.net/).
|
||||
* Add: Base layer "Yahoo Map", "Yahoo Satellite", "Yahoo Hybrid" (hidden) (http://maps.yahoo.com/).
|
||||
|
||||
2010-12-20 Robert Heel <rheel@1drop.de>
|
||||
* Add: Hover mode for markers.
|
||||
* Update: Use addJsFile function to include JS. Requires TYPO3 4.3.
|
||||
|
||||
2010-12-12 Robert Heel <rheel@1drop.de>
|
||||
* Bugfix: Same order of Base layer in FE and BE.
|
||||
|
||||
2010-11-27 Robert Heel <rheel@1drop.de>
|
||||
* Add: Base layer "Mapnik BW" (http://toolserver.org/~osm/styles/).
|
||||
* Add: TS option "external_control" to enable map control with GET or POST parameter zoom, lon, lat and layers.
|
||||
|
||||
2010-10-21 Robert Heel <rheel@1drop.de>
|
||||
* Add: TS option "static_layer" and plugin dropdown to change layer of static map.
|
||||
* Add: Static map info for Mapnik and CycleMap.
|
||||
* Update: OpenLayers to version 2.10.
|
||||
* Update: OpenStreetMap.js.
|
||||
|
||||
2010-09-22 Robert Heel <rheel@1drop.de>
|
||||
* Add: Allow percentaged width and height.
|
||||
* Add: Overlay layer "Hiking Paths" (http://osm.lonvia.de/world_hiking.html).
|
||||
|
||||
2010-07-30 Robert Heel <rheel@1drop.de>
|
||||
* Bugfix: fe_groups didn't work if user is member of multiple groups.
|
||||
|
||||
2010-07-24 Robert Heel <rheel@1drop.de>
|
||||
* Add: Plugin option for map center coordinates.
|
||||
* Bugfix: Use TYPO3 function to get coordinates.
|
||||
|
||||
2010-06-02 Robert Heel <rheel@1drop.de>
|
||||
* Bugfix: Extension key "ods_osm_search" was NOT loaded!
|
||||
|
||||
2010-06-02 Robert Heel <rheel@1drop.de>
|
||||
* Add: Cache for autocomplete longitude and latitude.
|
||||
* Add: Search service "http://nominatim.openstreetmap.org/".
|
||||
* Bugfix: Allow negative longitude.
|
||||
* Change: Swap order of appearance of lon & lat.
|
||||
* Change: Optimize database fields.
|
||||
|
||||
2010-05-25 Robert Heel <rheel@1drop.de>
|
||||
* Bugfix: JavaScript cleanup for IE8. (Thanks to Rolf Güssow)
|
||||
|
||||
2010-05-20 Robert Heel <rheel@1drop.de>
|
||||
* Bugifx: addFieldsToAllPalettesOfField initial available since TYPO3 4.3.
|
||||
* Bugfix: Escape javascript text parameter for popup content.
|
||||
* Bugfix: Ignore invalid markers set by TS.
|
||||
* Bugfix: Address records latitude default "-1" (no coordinates).
|
||||
* Bugfix: Extension didn't work if not press the update button after install.
|
||||
Thanks to Erik Sokoll for reporting these bugs.
|
||||
|
||||
2010-05-14 Robert Heel <rheel@1drop.de>
|
||||
* Add: no_marker option to hide map if no marker is set.
|
||||
* Add: Hook to change records.
|
||||
|
||||
2010-05-11 Robert Heel <rheel@1drop.de>
|
||||
* Bugfix: Disable multilanguage flexform.
|
||||
* Change: Sort backend items.
|
||||
|
||||
2010-05-10 Robert Heel <rheel@1drop.de>
|
||||
* Change: Show overlays if layerswitcher is disabled.
|
||||
|
||||
2010-05-09 Robert Heel <rheel@1drop.de>
|
||||
* Add: Base layer "ÖPNV Deutschland" (http://www.öpnvkarte.de/).
|
||||
* Add: Base layer "Hike & Bike Map" (http://www.hikebikemap.de/) (including overlays "Hillshading" and "By Night").
|
||||
* Change: Move getTileURL to main.js.
|
||||
|
||||
2010-05-05 Robert Heel <rheel@1drop.de>
|
||||
* Bugfix: Typo in backpath.
|
||||
* Change: Show base layer title in layerswitcher.
|
||||
* Add: TS option "static_script".
|
||||
* Add: Hidden base layer Bing maps.
|
||||
|
||||
2010-05-01 Robert Heel <rheel@1drop.de>
|
||||
* Change: Include "OpenStreetMap.js" only if needed.
|
||||
* Remove: TS option "path_openstreetmap" (can be changed in the layer element).
|
||||
* Add: Manual sorting of layers.
|
||||
* Add: Hidden base layer Google maps.
|
||||
|
||||
2010-04-27 Robert Heel <rheel@1drop.de>
|
||||
* Add: Update cached files after one week.
|
||||
|
||||
2010-04-22 Robert Heel <rheel@1drop.de>
|
||||
* Add: Option to update coordinates on every address change.
|
||||
|
||||
2010-04-10 Robert Heel <rheel@1drop.de>
|
||||
* Add: Layer field for static javascript and static url.
|
||||
* Add: Base layer "OpenPisteMap" (http://openpistemap.org/).
|
||||
* Add: First marker to static map.
|
||||
|
||||
2010-04-07 Robert Heel <rheel@1drop.de>
|
||||
* Incompatible change: Base layers as more flexible database elements. Please update your configuration if you didn't use Mapnik.
|
||||
* Incompatible change: Cleanup map control options: Renamed show_navigation to mouse_navigation, show_pan_zoom_bar to show_pan_zoom.
|
||||
* Add: Overlay layer "Seamarks" (http://openseamap.org/).
|
||||
* Add: TS constants.
|
||||
* Update: Documentation.
|
||||
|
||||
2010-04-02 Robert Heel <rheel@1drop.de>
|
||||
* Add: TS option for script path.
|
||||
* Add: TS option for additional layerswitcher options.
|
||||
* Add: CycleMap.
|
||||
|
||||
2010-04-01 Robert Heel <rheel@1drop.de>
|
||||
* Add: Layerswitcher. (Thanks to Markus Volkmer)
|
||||
* Add: Static Osmarender map.
|
||||
* Bugfix: Show fe_groups marker.
|
||||
* Bugfix: Allow negative values in offset.
|
||||
* Update: Documentation.
|
||||
|
||||
2010-03-18 Robert Heel <rheel@1drop.de>
|
||||
* Add: Get items from pages, fe_groups, tt_address_group.
|
||||
* Add: Set icon in group.
|
||||
* Add: Optional local javascript and image files.
|
||||
* Update: Documentation.
|
||||
|
||||
2010-03-15 Robert Heel <rheel@1drop.de>
|
||||
* Add: Marker popups.
|
||||
* Change: Javascript cleanup.
|
||||
* Update: Documentation.
|
||||
|
||||
2010-03-04 Robert Heel <rheel@1drop.de>
|
||||
* Add: Documentation.
|
||||
* Add: absRefPrefix.
|
||||
* Bugfix: Allow negative longitude.
|
||||
|
||||
2010-03-01 Robert Heel <rheel@1drop.de>
|
||||
* Add: Show GPX tracks.
|
||||
* Change: Optimize database fields.
|
||||
|
||||
2010-02-26 Robert Heel <rheel@1drop.de>
|
||||
* Add: Coordinate selection wizard.
|
||||
* Add: Coordinates in fe_users.
|
||||
|
||||
2010-02-24 Robert Heel <rheel@1drop.de>
|
||||
* initial code generated with kickstarter
|
||||
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2023 Alexander Bigga <alexander@bigga.de>
|
||||
* All rights reserved
|
||||
*
|
||||
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||
* free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The GNU General Public License can be found at
|
||||
* http://www.gnu.org/copyleft/gpl.html.
|
||||
*
|
||||
* This script is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
namespace Bobosch\OdsOsm\Backend\FormDataProvider;
|
||||
|
||||
/**
|
||||
* This class is inspired by the FlexFormManipulation::class of the
|
||||
* news extension by Georg Ringer
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Backend\Form\FormDataProviderInterface;
|
||||
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
|
||||
|
||||
/**
|
||||
* Manipulate flexforms of ods_osm_pi to ensure only available
|
||||
* tables are allowed to select records.
|
||||
*/
|
||||
class FlexFormManipulation implements FormDataProviderInterface
|
||||
{
|
||||
/**
|
||||
* Manipulate data of ods_osm_pi plugin.
|
||||
*
|
||||
* @param array $result
|
||||
* @return array
|
||||
*/
|
||||
public function addData(array $result): array
|
||||
{
|
||||
if ($result['tableName'] === 'tt_content'
|
||||
&& $result['databaseRow']['CType'] === 'list'
|
||||
&& $result['databaseRow']['list_type'] === 'ods_osm_pi1'
|
||||
&& is_array($result['processedTca']['columns']['pi_flexform']['config']['ds'])
|
||||
) {
|
||||
// get flexform data structure
|
||||
$dataStructure = $result['processedTca']['columns']['pi_flexform']['config']['ds'];
|
||||
|
||||
// check / manipulate data structure
|
||||
$dataStructure = $this->fixAllowedTables($dataStructure);
|
||||
|
||||
// set checked data structure
|
||||
$result['processedTca']['columns']['pi_flexform']['config']['ds'] = $dataStructure;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for optionally installed extensions and add the
|
||||
* corresponding tables to the list of allowed tables for marker.
|
||||
*
|
||||
* @param array &$dataStructure flexform structure
|
||||
* @return array Modified structure
|
||||
*/
|
||||
protected function fixAllowedTables(array $dataStructure): array
|
||||
{
|
||||
$markerAllowedTables = [ 'fe_users', 'fe_groups', 'pages', 'sys_category', 'tx_odsosm_track', 'tx_odsosm_vector' ];
|
||||
$markerPopupInitialAllowedTables = [ 'fe_users' ];
|
||||
|
||||
$extensions = [
|
||||
'tt_address' => 'tt_address',
|
||||
'calendarize' => 'tx_calendarize_domain_model_event'
|
||||
];
|
||||
|
||||
foreach ($extensions as $extension => $table) {
|
||||
if (ExtensionManagementUtility::isLoaded($extension)) {
|
||||
$markerAllowedTables[] = $table;
|
||||
$markerPopupInitialAllowedTables[] = $table;
|
||||
}
|
||||
}
|
||||
|
||||
// set manipulated value for marker -> config -> allowed
|
||||
if ($dataStructure['sheets']['sDEF']['ROOT']['el']['marker']['config']['allowed'] ?? false) {
|
||||
$dataStructure['sheets']['sDEF']['ROOT']['el']['marker']['config']['allowed'] = implode(',', $markerAllowedTables);
|
||||
}
|
||||
|
||||
// set manipulated value for marker_popup_initial -> config -> allowed
|
||||
if ($dataStructure['sheets']['sDEF']['ROOT']['el']['marker_popup_initial']['config']['allowed'] ?? false) {
|
||||
$dataStructure['sheets']['sDEF']['ROOT']['el']['marker_popup_initial']['config']['allowed'] = implode(',', $markerPopupInitialAllowedTables);
|
||||
}
|
||||
|
||||
return $dataStructure;
|
||||
}
|
||||
|
||||
}
|
||||
663
typo3conf/ext/ods_osm/Classes/Controller/PluginController.php
Normal file
@@ -0,0 +1,663 @@
|
||||
<?php
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2010 Robert Heel <typo3@bobosch.de>
|
||||
* All rights reserved
|
||||
*
|
||||
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||
* free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The GNU General Public License can be found at
|
||||
* http://www.gnu.org/copyleft/gpl.html.
|
||||
*
|
||||
* This script is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
namespace Bobosch\OdsOsm\Controller;
|
||||
|
||||
use Bobosch\OdsOsm\Div;
|
||||
use Bobosch\OdsOsm\Provider\BaseProvider;
|
||||
use TYPO3\CMS\Core\Database\Connection;
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Page\PageRenderer;
|
||||
use TYPO3\CMS\Core\Resource\FileRepository;
|
||||
use TYPO3\CMS\Core\Utility\ArrayUtility;
|
||||
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
|
||||
use TYPO3\CMS\Frontend\Plugin\AbstractPlugin;
|
||||
|
||||
/**
|
||||
* Plugin 'OpenStreetMap' for the 'ods_osm' extension.
|
||||
*
|
||||
* @author Robert Heel <typo3@bobosch.de>
|
||||
* @package TYPO3
|
||||
* @subpackage tx_odsosm
|
||||
*/
|
||||
class PluginController extends AbstractPlugin
|
||||
{
|
||||
/**
|
||||
* Same as class name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $prefixId = 'tx_odsosm_pi1';
|
||||
|
||||
/**
|
||||
* The extension key.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $extKey = 'ods_osm';
|
||||
|
||||
public $config;
|
||||
public $hooks;
|
||||
public $lats = [];
|
||||
public $lons = [];
|
||||
/** @var ConnectionPool */
|
||||
public $connectionPool = null;
|
||||
/** @var BaseProvider */
|
||||
protected $library;
|
||||
|
||||
public function init($conf): void
|
||||
{
|
||||
$this->pi_setPiVarDefaults();
|
||||
$this->pi_loadLL();
|
||||
$this->pi_initPIflexForm(); // Init FlexForm configuration for plugin
|
||||
|
||||
$this->hooks = [];
|
||||
if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ods_osm']['class.tx_odsosm_pi1.php'] ?? null)) {
|
||||
foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ods_osm']['class.tx_odsosm_pi1.php'] as $classRef) {
|
||||
$this->hooks[] = GeneralUtility::makeInstance($classRef);
|
||||
}
|
||||
}
|
||||
|
||||
$this->connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
|
||||
|
||||
/* --------------------------------------------------
|
||||
Configuration may be done in different places
|
||||
- FlexForm ($flex)
|
||||
- TypoScript ($conf)
|
||||
- extension settings
|
||||
-------------------------------------------------- */
|
||||
|
||||
$flex = [];
|
||||
$options = [
|
||||
'cluster',
|
||||
'cluster_radius',
|
||||
'height',
|
||||
'lat',
|
||||
'layer',
|
||||
'leaflet_layer',
|
||||
'library',
|
||||
'lon',
|
||||
'marker',
|
||||
'marker_popup_initial',
|
||||
'mouse_position',
|
||||
'openlayers_layer',
|
||||
'base_layer',
|
||||
'overlays',
|
||||
'overlays_active',
|
||||
'position',
|
||||
'show_layerswitcher',
|
||||
'layerswitcher_activationMode',
|
||||
'show_scalebar',
|
||||
'show_fullscreen',
|
||||
'show_popups',
|
||||
'staticmap_layer',
|
||||
'use_coords_only_nomarker',
|
||||
'width',
|
||||
'zoom',
|
||||
'enable_scrollwheelzoom',
|
||||
'enable_dragging',
|
||||
];
|
||||
// fill flex array, if there is a flexform data available
|
||||
if ($this->cObj->data['pi_flexform'] ?? null) {
|
||||
foreach ($options as $option) {
|
||||
$value = $this->pi_getFFvalue($this->cObj->data['pi_flexform'] ?? null, $option, 'sDEF');
|
||||
switch ($option) {
|
||||
case 'lat':
|
||||
case 'lon':
|
||||
if ($value != 0) {
|
||||
$flex[$option] = $value;
|
||||
}
|
||||
break;
|
||||
case 'marker':
|
||||
case 'marker_popup_initial':
|
||||
$flex[$option] = $this->splitGroup($value, 'tt_address');
|
||||
break;
|
||||
default:
|
||||
$flex[$option] = $value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($flex['library'] == 'staticmap' && !empty($flex['staticmap_layer'])) {
|
||||
$flex['layer'] = $flex['staticmap_layer'];
|
||||
} elseif (!empty($flex['base_layer'])) {
|
||||
$flex['layer'] = $flex['base_layer'];
|
||||
}
|
||||
}
|
||||
|
||||
// merge configs together into $this->config
|
||||
// 1. get extension configuration
|
||||
$this->config = Div::getConfig();
|
||||
// 2. get TypoScript settings
|
||||
ArrayUtility::mergeRecursiveWithOverrule($this->config, $conf);
|
||||
// 3. merge Flexform settings, but skip empty values.
|
||||
ArrayUtility::mergeRecursiveWithOverrule($this->config, $flex, true, false);
|
||||
|
||||
if (!is_array($this->config['marker'] ?? null)) {
|
||||
$this->config['marker'] = [];
|
||||
}
|
||||
if (is_array($conf['marker.'])) {
|
||||
foreach ($conf['marker.'] as $name => $value) {
|
||||
if (is_string($value) && !empty($value)) {
|
||||
if (!is_array($this->config['marker'][$name] ?? null)) {
|
||||
$this->config['marker'][$name] = [];
|
||||
}
|
||||
$this->config['marker'][$name] = array_merge($this->config['marker'][$name], explode(',', $value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->config['layer'] = explode(',', $this->config['layer'] . (!empty($this->config['overlays']) ? ',' . $this->config['overlays'] : ''));
|
||||
|
||||
if (is_numeric($this->config['height'])) {
|
||||
$this->config['height'] .= 'px';
|
||||
}
|
||||
if (is_numeric($this->config['width'])) {
|
||||
$this->config['width'] .= 'px';
|
||||
}
|
||||
|
||||
if ($this->config['show_layerswitcher'] ?? false) {
|
||||
$this->config['layers_visible'] = [];
|
||||
} else {
|
||||
$this->config['layers_visible'] = $this->config['layer'];
|
||||
}
|
||||
|
||||
if ($this->config['external_control'] ?? false) {
|
||||
if (GeneralUtility::_GP('lon')) {
|
||||
$this->config['lon'] = GeneralUtility::_GP('lon');
|
||||
}
|
||||
if (GeneralUtility::_GP('lat')) {
|
||||
$this->config['lat'] = GeneralUtility::_GP('lat');
|
||||
}
|
||||
if (GeneralUtility::_GP('zoom')) {
|
||||
$this->config['zoom'] = GeneralUtility::_GP('zoom');
|
||||
}
|
||||
if (GeneralUtility::_GP('layers')) {
|
||||
$this->config['layers_visible'] = explode(',', GeneralUtility::_GP('layers'));
|
||||
}
|
||||
if (GeneralUtility::_GP('records')) {
|
||||
$this->config['marker'] = $this->splitGroup(GeneralUtility::_GP('records'), 'tt_address');
|
||||
}
|
||||
}
|
||||
|
||||
// If EXT:calendarize is installed and the single view is called, we try to fetch the right event.
|
||||
if (ExtensionManagementUtility::isLoaded('calendarize')) {
|
||||
if (GeneralUtility::_GP('tx_calendarize_calendar')['index'] ?? false) {
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
->getQueryBuilderForTable('tx_calendarize_domain_model_index');
|
||||
|
||||
$result = $queryBuilder
|
||||
->select('foreign_uid')
|
||||
->from('tx_calendarize_domain_model_index')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq(
|
||||
'tx_calendarize_domain_model_index.uid',
|
||||
$queryBuilder->createNamedParameter((int) GeneralUtility::_GP('tx_calendarize_calendar')['index'], Connection::PARAM_INT)
|
||||
)
|
||||
)
|
||||
->setMaxResults(1)
|
||||
->executeQuery();
|
||||
|
||||
if ($row = $result->fetchAssociative()) {
|
||||
$this->config['marker']['tx_calendarize_domain_model_event'][] = $row['foreign_uid'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->config['id'] = 'osm_' . ($this->cObj->data['uid'] ?? uniqid());
|
||||
|
||||
$this->config['marker'] = $this->extractGroup($this->config['marker']);
|
||||
|
||||
// Show this marker's popup intially
|
||||
if (is_array($this->config['marker_popup_initial'])) {
|
||||
foreach ($this->config['marker_popup_initial'] as $table => $records) {
|
||||
foreach ($records as $uid) {
|
||||
if (isset($this->config['marker'][$table][$uid])) {
|
||||
$this->config['marker'][$table][$uid]['initial_popup'] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Library
|
||||
if (empty($this->config['library'])) {
|
||||
$this->config['library'] = 'leaflet';
|
||||
}
|
||||
$this->library = GeneralUtility::makeInstance('Bobosch\\OdsOsm\\Provider\\' . GeneralUtility::underscoredToUpperCamelCase($this->config['library']));
|
||||
$this->library->init($this->config);
|
||||
$this->library->cObj = $this->cObj;
|
||||
}
|
||||
|
||||
/**
|
||||
* The main method of the PlugIn
|
||||
*
|
||||
* @param string $content : The PlugIn content
|
||||
* @param array $conf : The PlugIn configuration
|
||||
*
|
||||
* @return string The content that is displayed on the website
|
||||
*/
|
||||
public function main($content, $conf)
|
||||
{
|
||||
$this->init($conf);
|
||||
|
||||
if ($this->config['marker'] || $this->config['no_marker']) {
|
||||
$content = $this->getMap();
|
||||
}
|
||||
|
||||
return $this->pi_wrapInBaseClass($content);
|
||||
}
|
||||
|
||||
public function splitGroup($group, $default = '')
|
||||
{
|
||||
$groups = explode(',', $group);
|
||||
foreach ($groups as $group) {
|
||||
$item = GeneralUtility::revExplode('_', $group, 2);
|
||||
if (count($item) == 1) {
|
||||
$record_ids[$default][] = $item[0];
|
||||
} else {
|
||||
$record_ids[$item[0]][] = $item[1];
|
||||
}
|
||||
}
|
||||
|
||||
return ($record_ids);
|
||||
}
|
||||
|
||||
private function extractGroup($record_ids)
|
||||
{
|
||||
$tables = Div::getTableConfig();
|
||||
|
||||
// if no markers are set, select current page to find records on it
|
||||
if (count($record_ids) == 0) {
|
||||
//@extensionScannerIgnoreLine
|
||||
$record_ids['pages'] = [$GLOBALS['TSFE']->id];
|
||||
}
|
||||
|
||||
// get all marker records on configured page.
|
||||
if (!empty($record_ids['pages'])) {
|
||||
foreach (array_keys($tables) as $table) {
|
||||
if ($table != 'tt_content') {
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
->getQueryBuilderForTable($table);
|
||||
|
||||
$result = $queryBuilder
|
||||
->select($table . '.uid')
|
||||
->from($table)->where($queryBuilder->expr()->in(
|
||||
$table . '.pid',
|
||||
$queryBuilder->createNamedParameter(
|
||||
$record_ids['pages'],
|
||||
Connection::PARAM_INT_ARRAY
|
||||
)
|
||||
))->executeQuery();
|
||||
|
||||
while ($resArray = $result->fetchAssociative()) {
|
||||
if (!in_array($resArray['uid'], $record_ids[$table] ?? [])) {
|
||||
$record_ids[$table][] = $resArray['uid'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get marker records from db
|
||||
$records = [];
|
||||
foreach ($record_ids as $table => $items) {
|
||||
$tc = $tables[$table] ?? [];
|
||||
$connection = $this->connectionPool
|
||||
->getConnectionForTable($table)
|
||||
->createSchemaManager()
|
||||
->tablesExist([$table]);
|
||||
|
||||
// table seems not available --> break to avoid exceptions
|
||||
if ($connection === false) {
|
||||
break;
|
||||
}
|
||||
foreach ($items as $item) {
|
||||
$item = (int) $item;
|
||||
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
->getQueryBuilderForTable($table);
|
||||
|
||||
// hint: language overlay e.g. of tt_address records is done automatically
|
||||
$result = $queryBuilder
|
||||
->select('*')
|
||||
->from($table)
|
||||
->where(
|
||||
$queryBuilder->expr()->eq(
|
||||
$table . '.uid',
|
||||
$queryBuilder->createNamedParameter((int) $item, Connection::PARAM_INT)
|
||||
)
|
||||
)->setMaxResults(1)->executeQuery();
|
||||
|
||||
if ($row = $result->fetchAssociative()) {
|
||||
// Group with relation to a field
|
||||
if (is_array($tc['FIND_IN_SET'] ?? null)) {
|
||||
foreach ($tc['FIND_IN_SET'] as $t => $f) {
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
->getQueryBuilderForTable($table);
|
||||
|
||||
$result = $queryBuilder
|
||||
->select('*')
|
||||
->from($t)
|
||||
->where(
|
||||
$queryBuilder->expr()->inSet(
|
||||
$f,
|
||||
$queryBuilder->createNamedParameter(
|
||||
(int) $item,
|
||||
Connection::PARAM_INT
|
||||
)
|
||||
)
|
||||
)->executeQuery();
|
||||
|
||||
while ($resArray = $result->fetchAssociative()) {
|
||||
$records[$t][$resArray['uid']] = $resArray;
|
||||
$records[$t][$resArray['uid']]['group_uid'] = $table . '_' . $row['uid'];
|
||||
$records[$t][$resArray['uid']]['group_title'] = $row['title'];
|
||||
$records[$t][$resArray['uid']]['group_description'] = $row['description'];
|
||||
$records[$t][$resArray['uid']]['tx_odsosm_marker'] = $row['tx_odsosm_marker'];
|
||||
$records[$t][$resArray['uid']]['longitude'] = $resArray[$tables[$t]['lon']];
|
||||
$records[$t][$resArray['uid']]['latitude'] = $resArray[$tables[$t]['lat']];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Group with mm relation
|
||||
if (is_array($tc['MM'] ?? null)) {
|
||||
foreach ($tc['MM'] as $t => $f) {
|
||||
$local = $f['local'];
|
||||
$mm = $f['mm'];
|
||||
$foreign = $f['foreign'];
|
||||
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($foreign);
|
||||
$constraints = Div::getConstraintsForQueryBuilder($foreign, $this->cObj, $queryBuilder);
|
||||
|
||||
// set uid
|
||||
$constraints[] = $queryBuilder->expr()->eq($local . '.uid', $queryBuilder->createNamedParameter($item, Connection::PARAM_INT));
|
||||
|
||||
$rows = $queryBuilder
|
||||
->select($foreign . '.*')
|
||||
->from($foreign)
|
||||
->join(
|
||||
$foreign,
|
||||
$mm,
|
||||
$mm,
|
||||
$queryBuilder->expr()->eq($foreign . '.uid', $queryBuilder->quoteIdentifier($mm . '.uid_foreign'))
|
||||
)
|
||||
->join(
|
||||
$mm,
|
||||
$local,
|
||||
$local,
|
||||
$queryBuilder->expr()->eq($local . '.uid', $queryBuilder->quoteIdentifier($mm . '.uid_local'))
|
||||
)
|
||||
->where(...$constraints)
|
||||
->executeQuery()
|
||||
->fetchAllAssociative();
|
||||
|
||||
foreach ($rows as $r) {
|
||||
$records[$t][$r['uid']] = $r;
|
||||
$records[$t][$r['uid']]['group_uid'] = $table . '_' . $row['uid'];
|
||||
$records[$t][$r['uid']]['group_title'] = $row['title'];
|
||||
$records[$t][$r['uid']]['group_description'] = $row['description'];
|
||||
$records[$t][$r['uid']]['tx_odsosm_marker'] = $row['tx_odsosm_marker'];
|
||||
$records[$t][$r['uid']]['longitude'] = $r[$tables[$t]['lon']];
|
||||
$records[$t][$r['uid']]['latitude'] = $r[$tables[$t]['lat']];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Marker
|
||||
if (isset($tc['lon'])) {
|
||||
$records[$table][$item] = $row;
|
||||
$records[$table][$item]['longitude'] = $row[$tc['lon']];
|
||||
$records[$table][$item]['latitude'] = $row[$tc['lat']];
|
||||
}
|
||||
|
||||
// Special element
|
||||
if ($tc === true && $row) {
|
||||
$records[$table][$item] = $row;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hook to change records
|
||||
foreach ($this->hooks as $hook) {
|
||||
if (method_exists($hook, 'changeRecords')) {
|
||||
$hook->changeRecords($records, $record_ids, $this);
|
||||
}
|
||||
}
|
||||
|
||||
// get lon & lat
|
||||
foreach ($records as $table => $items) {
|
||||
foreach ($items as $uid => $row) {
|
||||
switch ($table) {
|
||||
case 'tx_odsosm_track':
|
||||
case 'tx_odsosm_vector':
|
||||
if ($row['min_lon']) {
|
||||
$this->lons[] = (float) $row['min_lon'];
|
||||
$this->lats[] = (float) $row['min_lat'];
|
||||
$this->lons[] = (float) $row['max_lon'];
|
||||
$this->lats[] = (float) $row['max_lat'];
|
||||
} else {
|
||||
unset($records[$table][$uid]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$this->lons[] = (float) $row['longitude'];
|
||||
$this->lats[] = (float) $row['latitude'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No markers
|
||||
if (count($this->lons) == 0) {
|
||||
if ($this->config['no_marker'] == 1) {
|
||||
if (($this->config['lon'] ?? false) && ($this->config['lat'] ?? false)) {
|
||||
$this->lons[] = $this->config['lon'];
|
||||
$this->lats[] = $this->config['lat'];
|
||||
} else {
|
||||
$this->lons[] = $this->config['default_lon'];
|
||||
$this->lats[] = $this->config['default_lat'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ($records);
|
||||
}
|
||||
|
||||
public function getMap()
|
||||
{
|
||||
/* ==================================================
|
||||
Marker
|
||||
================================================== */
|
||||
// Get icon records
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
->getQueryBuilderForTable('tx_odsosm_marker');
|
||||
|
||||
$result = $queryBuilder
|
||||
->select('*')
|
||||
->from('tx_odsosm_marker')->where(1)->executeQuery();
|
||||
|
||||
$icons = [];
|
||||
while ($resArray = $result->fetchAssociative()) {
|
||||
$icons[$resArray['uid']] = $resArray;
|
||||
}
|
||||
|
||||
// Prepare markers
|
||||
$markers = $this->config['marker'];
|
||||
$local_cObj = GeneralUtility::makeInstance(ContentObjectRenderer::class);
|
||||
foreach ($markers as $table => &$items) {
|
||||
foreach ($items as $key => &$item) {
|
||||
$popup = is_string($this->config['popup.'][$table] ?? null) && is_array($this->config['popup.'][$table . '.'] ?? null) && $this->config['show_popups'];
|
||||
$icon = is_string($this->config['icon.'][$table] ?? null) && is_array($this->config['icon.'][$table . '.'] ?? null);
|
||||
if ($popup || $icon) {
|
||||
$local_cObj->start($item, $table);
|
||||
}
|
||||
|
||||
// Add popup information
|
||||
if ($popup) {
|
||||
$item['popup'] = $local_cObj->cObjGetSingle($this->config['popup.'][$table], $this->config['popup.'][$table . '.']);
|
||||
}
|
||||
|
||||
// Add icon information
|
||||
if ($item['tx_odsosm_marker'] ?? null) {
|
||||
$fileRepository = GeneralUtility::makeInstance(FileRepository::class);
|
||||
$fileObjects = $fileRepository->findByRelation('tx_odsosm_marker', 'icon', $item['tx_odsosm_marker']);
|
||||
if ($fileObjects) {
|
||||
$file = $fileObjects[0];
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
$item['tx_odsosm_marker'] = $icons[$item['tx_odsosm_marker']];
|
||||
$item['tx_odsosm_marker']['icon'] = $file;
|
||||
$item['tx_odsosm_marker']['type'] = 'image';
|
||||
} elseif ($icon) {
|
||||
if ($this->config['icon.'][$table] == 'IMAGE') {
|
||||
$info = $this->cObj->getImgResource(
|
||||
$this->config['icon.'][$table . '.']['file'] ?? '',
|
||||
$this->config['icon.'][$table . '.']['file.'] ?? []
|
||||
);
|
||||
$item['tx_odsosm_marker'] = [
|
||||
'icon' => $info['processedFile'],
|
||||
'type' => 'image',
|
||||
'size_x' => $info[0],
|
||||
'size_y' => $info[1],
|
||||
'offset_x' => -$info[0] / 2,
|
||||
'offset_y' => -$info[1],
|
||||
];
|
||||
} elseif ($this->config['icon.'][$table] == 'TEXT') {
|
||||
$conf = $this->config['icon.'][$table . '.'];
|
||||
$html = $local_cObj->cObjGetSingle(
|
||||
$this->config['icon.'][$table],
|
||||
$this->config['icon.'][$table . '.']
|
||||
);
|
||||
$item['tx_odsosm_marker'] = [
|
||||
'icon' => $html,
|
||||
'type' => 'html',
|
||||
'size_x' => $conf['size_x'],
|
||||
'size_y' => $conf['size_y'],
|
||||
'offset_x' => $conf['offset_x'],
|
||||
'offset_y' => $conf['offset_y'],
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ==================================================
|
||||
Layers
|
||||
================================================== */
|
||||
$layers = [];
|
||||
$baselayers = [];
|
||||
if (!empty(implode(',', $this->config['layer']))) {
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
->getQueryBuilderForTable('tx_odsosm_layer');
|
||||
|
||||
$result = $queryBuilder
|
||||
->select('*')
|
||||
->from('tx_odsosm_layer')
|
||||
->where(
|
||||
$queryBuilder->expr()->in(
|
||||
'tx_odsosm_layer.uid',
|
||||
$queryBuilder->createNamedParameter(
|
||||
$this->config['layer'],
|
||||
Connection::PARAM_INT_ARRAY
|
||||
)
|
||||
),
|
||||
)
|
||||
->add('orderBy', 'FIELD(uid, ' . implode(',', $this->config['layer']) . ')', true)
|
||||
->executeQuery();
|
||||
|
||||
while ($resArray = $result->fetchAssociative()) {
|
||||
$baselayers[$resArray['uid']] = $resArray;
|
||||
$baselayers[$resArray['uid']]['visible'] = false;
|
||||
}
|
||||
|
||||
// set visible flag
|
||||
if (isset($this->config['layers_visible'])) {
|
||||
foreach ($this->config['layers_visible'] as $key) {
|
||||
if ($baselayers[$key] ?? false) {
|
||||
$baselayers[$key]['visible'] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($this->config['overlays_active'])) {
|
||||
foreach (explode(',', $this->config['overlays_active']) as $key) {
|
||||
if ($baselayers[$key] ?? false) {
|
||||
$baselayers[$key]['visible'] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($baselayers as $uid => $layer) {
|
||||
if ($layer['overlay'] == 1) {
|
||||
$layers[1][] = $layer;
|
||||
} else {
|
||||
$layers[0][] = $layer;
|
||||
}
|
||||
}
|
||||
// $layers[0] = $baselayers;
|
||||
// $layers[1] = $overlays;
|
||||
$layers[2] = []; // markers will be filled in provider classes
|
||||
|
||||
/* ==================================================
|
||||
Map center
|
||||
================================================== */
|
||||
if ($this->config['lon'] ?? false || $this->config['use_coords_only_nomarker'] ?? false) {
|
||||
$lon = array_sum($this->lons) / count($this->lons);
|
||||
$lat = array_sum($this->lats) / count($this->lats);
|
||||
} else {
|
||||
$lon = (float)($this->config['lon'] ?? $this->config['default_lon']);
|
||||
$lat = (float)($this->config['lat'] ?? $this->config['default_lat']);
|
||||
}
|
||||
$zoom = (int)$this->config['zoom'];
|
||||
|
||||
/* ==================================================
|
||||
Map
|
||||
================================================== */
|
||||
$content = $this->library->getMap($layers, $markers, $lon, $lat, $zoom);
|
||||
$script = $this->library->getScript();
|
||||
$pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
|
||||
if ($script) {
|
||||
switch ($this->config['JSlibrary']) {
|
||||
case 'jquery':
|
||||
$pageRenderer->addJsFooterInlineCode(
|
||||
$this->config['id'],
|
||||
'$(document).ready(function() {' . $script . '});'
|
||||
);
|
||||
break;
|
||||
default:
|
||||
$pageRenderer->addJsFooterInlineCode(
|
||||
$this->config['id'],
|
||||
'document.addEventListener("DOMContentLoaded", function(){' . $script . '}, false);'
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ($content);
|
||||
}
|
||||
}
|
||||
576
typo3conf/ext/ods_osm/Classes/Div.php
Normal file
@@ -0,0 +1,576 @@
|
||||
<?php
|
||||
|
||||
namespace Bobosch\OdsOsm;
|
||||
|
||||
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
|
||||
use TYPO3\CMS\Core\Page\PageRenderer;
|
||||
use TYPO3\CMS\Core\Messaging\AbstractMessage;
|
||||
use TYPO3\CMS\Core\Log\Logger;
|
||||
use Doctrine\DBAL\FetchMode;
|
||||
use Doctrine\DBAL\ParameterType;
|
||||
use TYPO3\CMS\Core\Context\Context;
|
||||
use TYPO3\CMS\Core\Database\Connection;
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Database\Query\Restriction\FrontendRestrictionContainer;
|
||||
use TYPO3\CMS\Core\Http\RequestFactory;
|
||||
use TYPO3\CMS\Core\Log\LogManager;
|
||||
use TYPO3\CMS\Core\Messaging\FlashMessage;
|
||||
use TYPO3\CMS\Core\Messaging\FlashMessageService;
|
||||
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
|
||||
|
||||
class Div
|
||||
{
|
||||
const RESOURCE_BASE_PATH = 'EXT:ods_osm/Resources/Public/';
|
||||
|
||||
public static function getConstraintsForQueryBuilder(
|
||||
$table,
|
||||
ContentObjectRenderer $cObj,
|
||||
QueryBuilder $queryBuilder
|
||||
): array {
|
||||
$constraints = [];
|
||||
|
||||
if (is_string($table)) {
|
||||
$ctrl = $GLOBALS['TCA'][$table]['ctrl'];
|
||||
// Enable fields
|
||||
$queryBuilder->setRestrictions(GeneralUtility::makeInstance(FrontendRestrictionContainer::class));
|
||||
|
||||
// Version
|
||||
$constraints[] =
|
||||
$queryBuilder->expr()->gte($table . '.pid', $queryBuilder->createNamedParameter(0, Connection::PARAM_INT));
|
||||
|
||||
// Translation
|
||||
if ($ctrl['languageField'] ?? null) {
|
||||
$orConstraints = [
|
||||
$queryBuilder->expr()->eq(
|
||||
$table . '.' . $ctrl['languageField'],
|
||||
$queryBuilder->createNamedParameter(0, Connection::PARAM_INT)
|
||||
),
|
||||
$queryBuilder->expr()->eq(
|
||||
$table . '.' . $ctrl['languageField'],
|
||||
$queryBuilder->createNamedParameter(-1, Connection::PARAM_INT)
|
||||
),
|
||||
];
|
||||
|
||||
$languageAspect = GeneralUtility::makeInstance(Context::class)->getAspect('language');
|
||||
|
||||
if ($languageAspect->getContentId() && $ctrl['transOrigPointerField']) {
|
||||
$orConstraints[] = $queryBuilder->expr()->and($queryBuilder->expr()->eq($table . '.' . $ctrl['languageField'],
|
||||
$queryBuilder->createNamedParameter((int) $languageAspect->getContentId(), Connection::PARAM_INT)), $queryBuilder->expr()->eq($table . '.' . $ctrl['transOrigPointerField'],
|
||||
$queryBuilder->createNamedParameter(0, Connection::PARAM_INT)));
|
||||
}
|
||||
$constraints[] = $queryBuilder->expr()->or(...$orConstraints);
|
||||
}
|
||||
}
|
||||
return $constraints;
|
||||
}
|
||||
|
||||
public static function addJsFiles($scripts, $doc): void
|
||||
{
|
||||
$pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
|
||||
foreach ($scripts as $script) {
|
||||
$pageRenderer->addJsFooterFile(
|
||||
$script['src'],
|
||||
'text/javascript',
|
||||
true,
|
||||
false,
|
||||
'',
|
||||
false,
|
||||
'|',
|
||||
false,
|
||||
$script['sri'] ?? '',
|
||||
false,
|
||||
'anonymous'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the given address record with geo data from a geocoding service.
|
||||
*
|
||||
* Note that the record does not get update in database.
|
||||
*
|
||||
* @param array &$address Address record from database
|
||||
*
|
||||
* @return boolean True if the address got updated, false if not.
|
||||
*
|
||||
* @uses searchAddress()
|
||||
*/
|
||||
public static function updateAddress(&$address)
|
||||
{
|
||||
$config = self::getConfig(['cache_enabled', 'geo_service']);
|
||||
|
||||
self::splitAddressField($address);
|
||||
|
||||
// Use cache only when enabled
|
||||
if ($config['cache_enabled'] == 1) {
|
||||
$ll = self::searchAddress($address, 0);
|
||||
}
|
||||
|
||||
if (!$ll) {
|
||||
$search = $address;
|
||||
$ll = self::searchAddress($address, $config['geo_service']);
|
||||
// Update cache when enabled or needed for statistic
|
||||
if ($ll && $config['cache_enabled']) {
|
||||
self::updateCache($address, $search);
|
||||
}
|
||||
}
|
||||
|
||||
return $ll;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for the given address in one of the geocoding services and update
|
||||
* its data.
|
||||
*
|
||||
* Data lat, lon, zip and city may get updated.
|
||||
*
|
||||
* @param array &$address Address record from database
|
||||
* @param integer $service Geocoding service to use
|
||||
* - 0: internal caching database table
|
||||
* - 1: geonames.org
|
||||
* - 2: nominatim.openstreetmap.org
|
||||
*
|
||||
* @return boolean True if the address got updated, false if not.
|
||||
*/
|
||||
public static function searchAddress(&$address, $service = 0)
|
||||
{
|
||||
$config = self::getConfig(['default_country', 'geo_service_email', 'geo_service_user']);
|
||||
$ll = false;
|
||||
|
||||
$country = strtoupper(strlen($address['country'] ?? false) == 2 ? $address['country'] : $config['default_country']);
|
||||
$email = GeneralUtility::validEmail($config['geo_service_email']) ? $config['geo_service_email'] : ($_SERVER['SERVER_ADMIN'] ?? 'unkown@example.com');
|
||||
|
||||
if ($GLOBALS['TYPO3_CONF_VARS']['BE']['debug']) {
|
||||
$service_names = [0 => 'cache', 1 => 'geonames', 2 => 'nominatim'];
|
||||
self::getLogger()->debug('Search address using ' . $service_names[$service], $address);
|
||||
}
|
||||
|
||||
/** @var ConnectionPool $connectionPool */
|
||||
$connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
|
||||
$connection = $connectionPool->getConnectionForTable('tx_odsosm_geocache');
|
||||
|
||||
switch ($service) {
|
||||
case 0: // cache
|
||||
$where = [];
|
||||
if ($country) {
|
||||
$where[] = 'country=' . $connection->quote($country, ParameterType::STRING);
|
||||
}
|
||||
if ($address['city'] ?? false) {
|
||||
$where[] = '(city=' . $connection->quote($address['city'], ParameterType::STRING) . ' OR search_city=' . $connection->quote($address['city'], ParameterType::STRING) . ')';
|
||||
}
|
||||
if ($address['zip'] ?? false) {
|
||||
$where[] = 'zip=' . $connection->quote($address['zip'], ParameterType::STRING);
|
||||
}
|
||||
if ($address['street'] ?? false) {
|
||||
$where[] = 'street=' . $connection->quote($address['street'], ParameterType::STRING);
|
||||
}
|
||||
if ($address['housenumber'] ?? false) {
|
||||
$where[] = 'housenumber=' . $connection->quote($address['housenumber'], ParameterType::STRING);
|
||||
}
|
||||
|
||||
if ($where) {
|
||||
$where[] = 'deleted=0';
|
||||
|
||||
$res = $connection->executeQuery(
|
||||
'SELECT * FROM tx_odsosm_geocache WHERE ' . implode(' AND ', $where)
|
||||
);
|
||||
$row = $res->fetchAssociative();
|
||||
|
||||
if ($row) {
|
||||
$ll = true;
|
||||
|
||||
$set = [
|
||||
'tstamp' => time(),
|
||||
'cache_hit' => $row['cache_hit'] + 1,
|
||||
];
|
||||
$connection->update('tx_odsosm_geocache', $set, ['uid' => (int) $row['uid']]);
|
||||
|
||||
$address['lat'] = $row['lat'];
|
||||
$address['lon'] = $row['lon'];
|
||||
if ($row['zip'] ?? false) {
|
||||
$address['zip'] = $row['zip'];
|
||||
}
|
||||
if ($row['city'] ?? false) {
|
||||
$address['city'] = $row['city'];
|
||||
}
|
||||
if ($row['state'] ?? false) {
|
||||
$address['state'] = $row['state'];
|
||||
}
|
||||
if (empty($address['country'] ?? false)) {
|
||||
$address['country'] = $row['country'];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: // http://www.geonames.org/
|
||||
if ($country) {
|
||||
$query['country'] = $country;
|
||||
}
|
||||
if ($address['city'] ?? false) {
|
||||
$query['placename'] = $address['city'];
|
||||
}
|
||||
if ($address['zip'] ?? false) {
|
||||
$query['postalcode'] = $address['zip'];
|
||||
}
|
||||
|
||||
if ($query) {
|
||||
$query['maxRows'] = 1;
|
||||
$query['username'] = $config['geo_service_user'];
|
||||
|
||||
/** @var RequestFactory $requestFactory */
|
||||
$requestFactory = GeneralUtility::makeInstance(RequestFactory::class);
|
||||
$configuration = [
|
||||
'timeout' => 60,
|
||||
'headers' => [
|
||||
'Accept' => 'application/json',
|
||||
'User-Agent' => 'TYPO3 extension ods_osm/' . ExtensionManagementUtility::getExtensionVersion('ods_osm')
|
||||
],
|
||||
];
|
||||
|
||||
// secure endpoint available, too: https://secure.geonames.org/postalCodeSearchJSON?
|
||||
$response = $requestFactory->request('http://api.geonames.org/postalCodeSearchJSON?' . http_build_query($query, '', '&'), 'GET', $configuration);
|
||||
$content = $response->getBody()->getContents();
|
||||
$result = json_decode($content, true);
|
||||
|
||||
if ($result) {
|
||||
if ($result['status'] ?? false) {
|
||||
if ($GLOBALS['TYPO3_CONF_VARS']['BE']['debug']) {
|
||||
self::getLogger()->debug('GeoNames message', (array)$result['status']['message']);
|
||||
}
|
||||
self::flashMessage(
|
||||
(string)$result['status']['message'],
|
||||
'GeoNames message',
|
||||
AbstractMessage::WARNING
|
||||
);
|
||||
}
|
||||
|
||||
if ($result['postalCodes'][0] ?? false) {
|
||||
$ll = true;
|
||||
$address['lat'] = (string)$result['postalCodes'][0]['lat'];
|
||||
$address['lon'] = (string)$result['postalCodes'][0]['lng'];
|
||||
if ($result['postalCodes'][0]['postalCode'] ?? false) {
|
||||
$address['zip'] = (string)$result['postalCodes'][0]['postalCode'];
|
||||
}
|
||||
if ($result['postalCodes'][0]['placeName'] ?? false) {
|
||||
$address['city'] = (string)$result['postalCodes'][0]['placeName'];
|
||||
}
|
||||
if (empty($address['country'] ?? false)) {
|
||||
$address['country'] = (string)$result['postalCodes'][0]['countryCode'];
|
||||
}
|
||||
}
|
||||
} elseif ($GLOBALS['TYPO3_CONF_VARS']['BE']['debug'] ?? false) {
|
||||
self::getLogger()->error('No valid response from GeoNames service.');
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: // http://nominatim.openstreetmap.org/
|
||||
$query['country'] = $country;
|
||||
$query['email'] = $email;
|
||||
$query['addressdetails'] = 1;
|
||||
$query['format'] = 'jsonv2';
|
||||
|
||||
if ($address['type'] == 'structured') {
|
||||
if ($address['city'] ?? false) {
|
||||
$query['city'] = $address['city'];
|
||||
}
|
||||
if ($address['zip'] ?? false) {
|
||||
$query['postalcode'] = $address['zip'];
|
||||
}
|
||||
if ($address['street'] ?? false) {
|
||||
$query['street'] = $address['street'];
|
||||
}
|
||||
if ($address['housenumber'] ?? false) {
|
||||
$query['street'] = $address['housenumber'] . ' ' . $query['street'];
|
||||
}
|
||||
|
||||
if ($GLOBALS['TYPO3_CONF_VARS']['BE']['debug'] ?? false) {
|
||||
self::getLogger()->debug('Nominatim structured', $query);
|
||||
}
|
||||
$ll = self::searchAddressNominatim($query, $address);
|
||||
|
||||
if (!$ll && ($query['postalcode'] ?? false)) {
|
||||
unset($query['postalcode']);
|
||||
|
||||
if ($GLOBALS['TYPO3_CONF_VARS']['BE']['debug'] ?? false) {
|
||||
self::getLogger()->debug('Nominatim retrying without zip', $query);
|
||||
}
|
||||
$ll = self::searchAddressNominatim($query, $address);
|
||||
}
|
||||
}
|
||||
|
||||
if ($address['type'] == 'unstructured') {
|
||||
$query['q'] = $address['address'];
|
||||
|
||||
if ($GLOBALS['TYPO3_CONF_VARS']['BE']['debug'] ?? false) {
|
||||
self::getLogger()->debug('Nominatim unstructured', $query);
|
||||
}
|
||||
$ll = self::searchAddressNominatim($query, $address);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if ($GLOBALS['TYPO3_CONF_VARS']['BE']['debug'] ?? false) {
|
||||
if ($ll) {
|
||||
self::getLogger()->debug('Return address', $address);
|
||||
} else {
|
||||
self::getLogger()->debug('No address found.');
|
||||
}
|
||||
}
|
||||
|
||||
return $ll;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for the given address in Nominatim service.
|
||||
*
|
||||
* Data lat, lon, zip and city may get updated.
|
||||
*
|
||||
* @param array $query The query sent to the nominatim API
|
||||
* @param array &$address Address record from database
|
||||
*
|
||||
* @return boolean True if the address was found and got updated.
|
||||
*/
|
||||
protected static function searchAddressNominatim($query, &$address)
|
||||
{
|
||||
$ll = false;
|
||||
|
||||
/** @var RequestFactory $requestFactory */
|
||||
$requestFactory = GeneralUtility::makeInstance(RequestFactory::class);
|
||||
$configuration = [
|
||||
'timeout' => 60,
|
||||
'headers' => [
|
||||
'Accept' => 'application/json',
|
||||
'User-Agent' => 'TYPO3 extension ods_osm/' . ExtensionManagementUtility::getExtensionVersion('ods_osm')
|
||||
],
|
||||
];
|
||||
|
||||
$response = $requestFactory->request('https://nominatim.openstreetmap.org/search?' . http_build_query($query, '', '&'), 'GET', $configuration);
|
||||
$content = $response->getBody()->getContents();
|
||||
$result = json_decode($content, true);
|
||||
|
||||
// Save value in cache
|
||||
if ($result) {
|
||||
// take the first result
|
||||
if ($result[0] ?? false) {
|
||||
$ll = true;
|
||||
$address['lat'] = (string)$result[0]['lat'];
|
||||
$address['lon'] = (string)$result[0]['lon'];
|
||||
if ($result[0]['address']['road'] ?? false) {
|
||||
$address['street'] = (string)$result[0]['address']['road'];
|
||||
}
|
||||
if ($result[0]['address']['house_number'] ?? false) {
|
||||
$address['housenumber'] = (string)$result[0]['address']['house_number'];
|
||||
}
|
||||
if ($result[0]['address']['postcode'] ?? false) {
|
||||
$address['zip'] = (string)$result[0]['address']['postcode'];
|
||||
}
|
||||
if ($result[0]['address']['city'] ?? false) {
|
||||
$address['city'] = $result[0]['address']['city'];
|
||||
} else if ($result[0]['address']['village'] ?? false) {
|
||||
$address['city'] = (string)$result[0]['address']['village'];
|
||||
}
|
||||
if ($result[0]['address']['state'] ?? false) {
|
||||
$address['state'] = (string)$result[0]['address']['state'];
|
||||
}
|
||||
if (($result[0]['address']['country_code'] ?? false) && empty($address['country'] ?? false)) {
|
||||
$address['country'] = strtoupper((string)$result[0]['address']['country_code']);
|
||||
}
|
||||
}
|
||||
} elseif ($GLOBALS['TYPO3_CONF_VARS']['BE']['debug'] ?? false) {
|
||||
self::getLogger()->error('No valid response from Nominatim service.');
|
||||
}
|
||||
|
||||
return $ll;
|
||||
}
|
||||
|
||||
public static function flashMessage($message, $title, $status): void
|
||||
{
|
||||
/** @var FlashMessage $flashMessage */
|
||||
$flashMessage = GeneralUtility::makeInstance(
|
||||
FlashMessage::class,
|
||||
$message,
|
||||
$title,
|
||||
$status
|
||||
);
|
||||
/** @var FlashMessageService $flashMessageService */
|
||||
$flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
|
||||
$flashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
|
||||
$flashMessageQueue->addMessage($flashMessage);
|
||||
}
|
||||
|
||||
public static function updateCache($address, $search = []): void
|
||||
{
|
||||
$set = [
|
||||
'search_city' => $search['city'] ?? '',
|
||||
'country' => $address['country'] ?? '',
|
||||
'state' => $address['state'] ?? '',
|
||||
'city' => $address['city'] ?? '',
|
||||
'zip' => $address['zip'] ?? '',
|
||||
'street' => $address['street'] ?? '',
|
||||
'housenumber' => $address['housenumber'] ?? '',
|
||||
];
|
||||
|
||||
/** @var ConnectionPool $connectionPool */
|
||||
$connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
|
||||
$connection = $connectionPool->getConnectionForTable('tx_odsosm_geocache');
|
||||
|
||||
$res = $connection->select(
|
||||
['*'], 'tx_odsosm_geocache', $set
|
||||
);
|
||||
$row = $res->fetchAssociative();
|
||||
if ($row) {
|
||||
$set = [
|
||||
'tstamp' => time(),
|
||||
'service_hit' => $row['service_hit'] + 1,
|
||||
];
|
||||
$connection->update('tx_odsosm_geocache', $set, ['uid' => (int) $row['uid']]);
|
||||
} else {
|
||||
$set['tstamp'] = time();
|
||||
$set['crdate'] = time();
|
||||
$set['service_hit'] = 1;
|
||||
$set['lat'] = $address['lat'];
|
||||
$set['lon'] = $address['lon'];
|
||||
$connection->insert('tx_odsosm_geocache', $set);
|
||||
}
|
||||
}
|
||||
|
||||
public static function splitAddressField(&$address): void
|
||||
{
|
||||
// Address field contains street if country, city or zip is set
|
||||
if (($address['country'] ?? false) || ($address['city'] ?? false) || ($address['zip'] ?? false)) {
|
||||
$address['type'] = 'structured';
|
||||
if ($address['address'] && !($address['street'] ?? false)) {
|
||||
$address['street'] = $address['address'];
|
||||
}
|
||||
if (!($address['housenumber'] ?? false) && ($address['street'] ?? false)) {
|
||||
// Split street and house number
|
||||
preg_match('/^(.+)\s(\d+(\s*[^\d\s]+)*)$/', $address['street'], $matches);
|
||||
if ($matches) {
|
||||
$address['street'] = $matches[1];
|
||||
$address['housenumber'] = $matches[2];
|
||||
}
|
||||
}
|
||||
} elseif ($address['address'] ?? false) {
|
||||
$address['type'] = 'unstructured';
|
||||
} else {
|
||||
$address['type'] = 'empty';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get extension configuration, and if not available use
|
||||
* default configuration. Optional parameter checks if
|
||||
* single value is available.
|
||||
*
|
||||
* @param array $values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getConfig($values = [])
|
||||
{
|
||||
$config = $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['ods_osm'] ?? [];
|
||||
$getDefault = [];
|
||||
|
||||
if ($config && is_array($values) && count($values)) {
|
||||
foreach ($values as $value) {
|
||||
if (!isset($config[$value])) {
|
||||
$getDefault[] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($config) || count($getDefault)) {
|
||||
$default = parse_ini_file(ExtensionManagementUtility::extPath('ods_osm') . 'ext_conf_template.txt');
|
||||
if (empty($config)) {
|
||||
$config = $default;
|
||||
} else {
|
||||
foreach ($getDefault as $value) {
|
||||
$config[$value] = $default[$value];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
public static function getTableConfig($table = false)
|
||||
{
|
||||
$tables = [
|
||||
'fe_groups' => [
|
||||
'FIND_IN_SET' => [
|
||||
'fe_users' => 'usergroup',
|
||||
],
|
||||
],
|
||||
'fe_users' => [
|
||||
'FORMAT' => '%01.6f',
|
||||
'lon' => 'tx_odsosm_lon',
|
||||
'lat' => 'tx_odsosm_lat',
|
||||
'address' => 'address',
|
||||
'zip' => 'zip',
|
||||
'city' => 'city',
|
||||
'country' => 'country',
|
||||
],
|
||||
'tt_content' => [
|
||||
'FORMAT' => '%01.6f',
|
||||
'lon' => 'lon',
|
||||
'lat' => 'lat',
|
||||
],
|
||||
'tx_odsosm_track' => true,
|
||||
'tx_odsosm_vector' => true,
|
||||
'sys_category' => [
|
||||
'MM' => [
|
||||
'tt_address' => [
|
||||
'local' => 'sys_category',
|
||||
'mm' => 'sys_category_record_mm',
|
||||
'foreign' => 'tt_address'
|
||||
]
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
// load configuration for calendarize only if extension is loaded
|
||||
if (ExtensionManagementUtility::isLoaded('calendarize')) {
|
||||
$tables['tx_calendarize_domain_model_event'] = [
|
||||
'FORMAT' => '%01.6f',
|
||||
'lon' => 'tx_odsosm_lon',
|
||||
'lat' => 'tx_odsosm_lat',
|
||||
'address' => 'location',
|
||||
];
|
||||
}
|
||||
// load configuration for tt_address only if extension is loaded
|
||||
if (ExtensionManagementUtility::isLoaded('tt_address')) {
|
||||
$tables['tt_address'] = [
|
||||
'FORMAT' => '%01.11f',
|
||||
'lon' => 'longitude',
|
||||
'lat' => 'latitude',
|
||||
'address' => 'address',
|
||||
'zip' => 'zip',
|
||||
'city' => 'city',
|
||||
'state' => 'region',
|
||||
'country' => 'country',
|
||||
];
|
||||
}
|
||||
|
||||
if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ods_osm']['tables'] ?? null)) {
|
||||
$tables = array_merge($tables, $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ods_osm']['tables']);
|
||||
}
|
||||
|
||||
return $table ? ($tables[$table] ?? []) : $tables;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Logger
|
||||
*/
|
||||
protected static function getLogger()
|
||||
{
|
||||
/** @var $loggerManager LogManager */
|
||||
$loggerManager = GeneralUtility::makeInstance(LogManager::class);
|
||||
|
||||
return $loggerManager->getLogger(static::class);
|
||||
}
|
||||
|
||||
}
|
||||
16
typo3conf/ext/ods_osm/Classes/Evaluation/LonLat.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace Bobosch\OdsOsm\Evaluation;
|
||||
|
||||
class LonLat
|
||||
{
|
||||
public function returnFieldJS(): string
|
||||
{
|
||||
return "return value;";
|
||||
}
|
||||
|
||||
public function evaluateFieldValue($value, $is_in, &$set): string
|
||||
{
|
||||
return sprintf('%01.6f', $value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Bobosch\OdsOsm\EventListener;
|
||||
|
||||
use HDNET\Calendarize\Register;
|
||||
use TYPO3\CMS\Core\Database\Event\AlterTableDefinitionStatementsEvent;
|
||||
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
|
||||
|
||||
class CalendarizeOdsOsmSqlListener
|
||||
{
|
||||
public function __invoke(AlterTableDefinitionStatementsEvent $event): void
|
||||
{
|
||||
if (ExtensionManagementUtility::isLoaded('calendarize')) {
|
||||
$event->addSqlData($this->getCalendarizeDatabaseString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the calendarize string for the registered tables.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getCalendarizeDatabaseString()
|
||||
{
|
||||
$sql = [];
|
||||
foreach (Register::getRegister() as $configuration) {
|
||||
if ($configuration['tableName'] == 'tx_calendarize_domain_model_event') {
|
||||
$sql[] = "CREATE TABLE " . $configuration['tableName'] . " (
|
||||
tx_odsosm_lon decimal(9,6) NOT NULL DEFAULT '0.000000',
|
||||
tx_odsosm_lat decimal(8,6) NOT NULL DEFAULT '0.000000',
|
||||
);";
|
||||
}
|
||||
}
|
||||
|
||||
return implode(LF, $sql);
|
||||
}
|
||||
}
|
||||
215
typo3conf/ext/ods_osm/Classes/Provider/BaseProvider.php
Normal file
@@ -0,0 +1,215 @@
|
||||
<?php
|
||||
|
||||
namespace Bobosch\OdsOsm\Provider;
|
||||
|
||||
use Bobosch\OdsOsm\Div;
|
||||
use TYPO3\CMS\Core\Page\PageRenderer;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
|
||||
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
|
||||
|
||||
abstract class BaseProvider
|
||||
{
|
||||
/** @var ContentObjectRenderer */
|
||||
public $cObj; // Must set from instantiating class
|
||||
protected $config;
|
||||
protected $script;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected $pageRenderer;
|
||||
|
||||
/** @var array keeping all JavaScripts to be included */
|
||||
protected $scripts = [];
|
||||
|
||||
protected $layers = [
|
||||
0 => [], // Base
|
||||
1 => [], // Overlay
|
||||
2 => [], // Marker
|
||||
];
|
||||
|
||||
// Implement these functions
|
||||
public function getMapCore($backpath = '')
|
||||
{
|
||||
}
|
||||
|
||||
public function getMapMain()
|
||||
{
|
||||
}
|
||||
|
||||
public function getMapCenter($lat, $lon, $zoom)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getLayer($layer, $i, $backpath = '')
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getMarker($item, $table)
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get JavaScript code for fulltext button
|
||||
*
|
||||
* @return string The JavaScript to add the fullscreen button
|
||||
*/
|
||||
protected function getFullScreen()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function init($config): void
|
||||
{
|
||||
$this->config = $config;
|
||||
$this->pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getMap($layers, $markers, $lon, $lat, $zoom)
|
||||
{
|
||||
$this->getMapCore();
|
||||
|
||||
$this->layers = $layers;
|
||||
|
||||
$baselayers = $layers[0] ?? null;
|
||||
$overlays = $layers[1] ?? null;
|
||||
|
||||
$this->script = "
|
||||
" . $this->getMapMain() . "
|
||||
" . $this->getBaseLayers($baselayers) . "
|
||||
" . $this->getOverlayLayers($overlays) . "
|
||||
" . $this->getMapCenter($lat, $lon, $zoom) . "
|
||||
" . $this->getMarkers($markers);
|
||||
|
||||
if (($this->config['show_layerswitcher'] ?? null) && ($this->config['show_layerswitcher'] > 0)) {
|
||||
$this->script .= $this->getLayerSwitcher() . "\n";
|
||||
}
|
||||
|
||||
if ($this->config['show_fullscreen'] ?? null) {
|
||||
$this->script .= $this->getFullScreen() . "\n";
|
||||
}
|
||||
|
||||
Div::addJsFiles($this->scripts, null);
|
||||
|
||||
return $this->getHtml();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getBaseLayers($layers, $backpath = '')
|
||||
{
|
||||
// Main layer
|
||||
$i = 0;
|
||||
$jsBaseLayer = [];
|
||||
if (is_array($layers) && !empty($layers)) {
|
||||
foreach ($layers as $layer) {
|
||||
$jsBaseLayer[] = $this->getLayer($layer, $i, $backpath);
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
|
||||
return implode("\n", ($jsBaseLayer));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getOverlayLayers($layers, $backpath = '')
|
||||
{
|
||||
// Main layer
|
||||
$i = 0;
|
||||
$jsOverlayLayer = [];
|
||||
if (is_array($layers) && !empty($layers)) {
|
||||
foreach ($layers as $layer) {
|
||||
$jsOverlayLayer[] = $this->getLayer($layer, $i, $backpath);
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
|
||||
return implode("\n", ($jsOverlayLayer));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getScript()
|
||||
{
|
||||
return $this->script;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getMarkers($markers)
|
||||
{
|
||||
$jsMarker = '';
|
||||
foreach ($markers as $table => $items) {
|
||||
foreach ($items as $item) {
|
||||
$jsMarker .= $this->getMarker($item, $table);
|
||||
}
|
||||
}
|
||||
|
||||
return $jsMarker;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getLayerSwitcher()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getHtml()
|
||||
{
|
||||
$mousePosition = '';
|
||||
$popupcode = '';
|
||||
if ($this->config['library'] == 'openlayers') {
|
||||
if ($this->config['mouse_position']) {
|
||||
$mousePosition = '<div id="mouse-position-' . $this->config['id'] . '">' . LocalizationUtility::translate('mouse_position', 'OdsOsm') . ': </div>';
|
||||
}
|
||||
$popupcode = '
|
||||
<div id="popup" class="ol-popup">
|
||||
<a href="#" id="popup-closer" class="ol-popup-closer"></a>
|
||||
<div id="popup-content"></div>
|
||||
</div>';
|
||||
}
|
||||
return '<div style="width:' . $this->config['width'] . '; height:' . $this->config['height'] . '; " id="' . $this->config['id'] . '"></div>' . $mousePosition . $popupcode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getTileUrl($layer)
|
||||
{
|
||||
if (strpos($layer['tile_url'], '://') !== false) {
|
||||
return $layer['tile_url'];
|
||||
}
|
||||
// if protocoll is missing, we add http:// or https://
|
||||
if ($layer['tile_https'] == 1) {
|
||||
return 'https://' . $layer['tile_url'];
|
||||
}
|
||||
return 'http://' . $layer['tile_url'];
|
||||
}
|
||||
|
||||
public function setContentObjectRenderer(ContentObjectRenderer $cObj): void
|
||||
{
|
||||
$this->cObj = $cObj;
|
||||
}
|
||||
}
|
||||
355
typo3conf/ext/ods_osm/Classes/Provider/Leaflet.php
Normal file
@@ -0,0 +1,355 @@
|
||||
<?php
|
||||
|
||||
namespace Bobosch\OdsOsm\Provider;
|
||||
|
||||
use Bobosch\OdsOsm\Div;
|
||||
use TYPO3\CMS\Core\Core\Environment;
|
||||
use TYPO3\CMS\Core\Resource\FileRepository;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Core\Utility\PathUtility;
|
||||
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
|
||||
|
||||
class Leaflet extends BaseProvider
|
||||
{
|
||||
protected $path_res;
|
||||
protected $path_leaflet;
|
||||
|
||||
public function getMapCore($backpath = ''): void
|
||||
{
|
||||
$this->path_res = ($backpath ? $backpath :
|
||||
PathUtility::getAbsoluteWebPath(
|
||||
GeneralUtility::getFileAbsFileName(Div::RESOURCE_BASE_PATH . 'JavaScript/Leaflet/')
|
||||
)
|
||||
);
|
||||
$this->path_leaflet = ($this->config['local_js'] ? $this->path_res . 'Core/' : 'https://unpkg.com/leaflet@1.9.4/dist/');
|
||||
$this->pageRenderer->addCssFile($this->path_leaflet . 'leaflet.css');
|
||||
$this->scripts['leaflet'] = [
|
||||
'src' => $this->path_leaflet . 'leaflet.js',
|
||||
'sri' => 'sha384-cxOPjt7s7Iz04uaHJceBmS+qpjv2JkIHNVcuOrM+YHwZOmJGBXI00mdUXEq65HTH'
|
||||
];
|
||||
}
|
||||
|
||||
public function getMapMain()
|
||||
{
|
||||
$controls = [];
|
||||
if ($this->config['show_scalebar']) {
|
||||
$controls['scalebar'] = 'new L.control.scale()';
|
||||
}
|
||||
|
||||
$vars = '';
|
||||
foreach ($controls as $var => $obj) {
|
||||
$vars .= "\n\t\t\t" . $this->config['id'] . '.addControl(' . $obj . ");";
|
||||
}
|
||||
|
||||
$jsMain =
|
||||
$this->config['id'] . "=new L.Map('" . $this->config['id'] . "',
|
||||
{scrollWheelZoom: " .((!isset($this->config['enable_scrollwheelzoom']) || $this->config['enable_scrollwheelzoom'] == '1') ? 'true' : 'false'). ",
|
||||
dragging: " .((!isset($this->config['enable_dragging']) || $this->config['enable_dragging'] == '1') ? 'true' : 'false'). "});
|
||||
L.Icon.Default.imagePath='" . $this->path_leaflet . "images/';"
|
||||
. $vars;
|
||||
if ($this->config['cluster']) {
|
||||
$this->pageRenderer->addCssFile($this->path_res . 'leaflet-markercluster/MarkerCluster.css');
|
||||
$this->pageRenderer->addCssFile($this->path_res . 'leaflet-markercluster/MarkerCluster.Default.css');
|
||||
$this->scripts['leaflet-markercluster'] = [
|
||||
'src' => $this->path_res . 'leaflet-markercluster/leaflet.markercluster.js'
|
||||
];
|
||||
}
|
||||
|
||||
return $jsMain;
|
||||
}
|
||||
|
||||
protected function getLayer($layer, $i, $backpath = '')
|
||||
{
|
||||
if ($layer['tile_url']) {
|
||||
$options = [];
|
||||
if ($layer['min_zoom']) {
|
||||
$options['minZoom'] = $layer['min_zoom'];
|
||||
}
|
||||
if ($layer['max_zoom']) {
|
||||
$options['maxZoom'] = $layer['max_zoom'];
|
||||
}
|
||||
if ($layer['subdomains']) {
|
||||
$options['subdomains'] = $layer['subdomains'];
|
||||
}
|
||||
if ($layer['attribution']) {
|
||||
$options['attribution'] = $layer['attribution'];
|
||||
}
|
||||
|
||||
$jsLayer = 'new L.TileLayer(\'' . $this->getTileUrl($layer) . '\',' . json_encode($options) . ');';
|
||||
}
|
||||
|
||||
$jsLayer = "\n\t\t\tvar layer_" . $layer['uid'] . ' = ' . $jsLayer;
|
||||
|
||||
// only show first base layer on the map
|
||||
if (($layer['overlay'] == 1 && $layer['visible']) || ($i == 0 && $layer['overlay'] == 0)) {
|
||||
$jsLayer .= "\n\t\t\t" . $this->config['id'] . '.addLayer(layer_' . $layer['uid'] . ');';
|
||||
}
|
||||
|
||||
return $jsLayer;
|
||||
}
|
||||
|
||||
protected function getLayerSwitcher()
|
||||
{
|
||||
$base = [];
|
||||
if (is_array($this->layers[0] ?? null) && count($this->layers[0]) > 1) {
|
||||
foreach ($this->layers[0] as $layer) {
|
||||
$base[] = '"' . $layer['title'] . '":' . ($layer['table'] ?? 'layer') . '_' . $layer['uid'];
|
||||
}
|
||||
}
|
||||
$overlay = [];
|
||||
if (is_array($this->layers[1] ?? null)) {
|
||||
foreach ($this->layers[1] as $layer) {
|
||||
if (!empty($layer['gid'])) {
|
||||
$overlay[] = '"' . $layer['title'] . '":' . $layer['gid'];
|
||||
} else {
|
||||
$overlay[] = '"' . $layer['title'] . '":' . ($layer['table'] ?? 'layer') . '_' . $layer['uid'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($base) && empty($overlay)) {
|
||||
return '';
|
||||
}
|
||||
return 'var layersControl=new L.Control.Layers({' . implode(',', $base) . '},{' . implode(',', $overlay) . '}' . ($this->config['show_layerswitcher'] == 2 ? ',{collapsed:false}' : '') . ');
|
||||
' . $this->config['id'] . '.addControl(layersControl);';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the fullscreen button
|
||||
*
|
||||
* @return string The JavaScript to add the fullscreen button
|
||||
*/
|
||||
public function getFullScreen()
|
||||
{
|
||||
// load leaflet.fullscreen plugin
|
||||
$this->scripts['leaflet-fullscreen'] = [
|
||||
'src' => $this->path_res . 'leaflet-fullscreen/Control.FullScreen.js',
|
||||
'sri' => 'sha384-TqFtkYBnYsrP2JCfIv/oLQxS9L6xpaIV9xnaI2UGMK25cJsTtQXZIU6WGQ7daT0Z'
|
||||
];
|
||||
$this->pageRenderer->addCssFile($this->path_res . 'leaflet-fullscreen/Control.FullScreen.css');
|
||||
|
||||
return "L.control.fullscreen({
|
||||
position: 'topleft',
|
||||
title: 'Full Screen',
|
||||
titleCancel: 'Exit fullscreen mode',
|
||||
forceSeparateButton: true,
|
||||
forcePseudoFullscreen: true, // force use of pseudo full screen even if full screen API is available, default false
|
||||
fullscreenElement: false // Dom element to render in full screen, false by default, fallback to map._container
|
||||
}).addTo(" . $this->config['id'] . ");";
|
||||
}
|
||||
|
||||
public function getMapCenter($lat, $lon, $zoom)
|
||||
{
|
||||
$return = 'var center = new L.LatLng(' . json_encode($lat) . ',' . json_encode($lon) . ');' . $this->config['id'] . '.setView(center,' . $zoom . ');';
|
||||
if ($this->config['position']) {
|
||||
$return .= $this->config['id'] . '.locate();' . $this->config['id'] . '.on("locationfound",function(e){var radius=e.accuracy/2;L.circle(e.latlng,radius).addTo(' . $this->config['id'] . ');});';
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
protected function getMarkers($markers)
|
||||
{
|
||||
$jsMarker = parent::getMarkers($markers);
|
||||
|
||||
foreach ($this->layers[2] as $group_uid => $group) {
|
||||
if ($this->config['cluster']) {
|
||||
$jsMarker .= 'var ' . $group_uid . ' = new L.MarkerClusterGroup({maxClusterRadius:' . (int)$this->config['cluster_radius'] . '});' . "\n";
|
||||
foreach ($group as $jsElementVar) {
|
||||
$jsMarker .= $group_uid . '.addLayer(' . $jsElementVar . ');' . "\n";
|
||||
}
|
||||
} else {
|
||||
$jsMarker .= 'var ' . $group_uid . ' = L.layerGroup([' . implode(',', $group) . ']);' . "\n";
|
||||
}
|
||||
$jsMarker .= $this->config['id'] . '.addLayer(' . $group_uid . ');' . "\n";
|
||||
}
|
||||
|
||||
return $jsMarker;
|
||||
}
|
||||
|
||||
protected function getMarker($item, $table)
|
||||
{
|
||||
$jsMarker = '';
|
||||
$jsElementVar = $table . '_' . $item['uid'];
|
||||
$fileRepository = GeneralUtility::makeInstance(FileRepository::class);
|
||||
$jsElementVarsForPopup = [];
|
||||
|
||||
switch ($table) {
|
||||
case 'tx_odsosm_track':
|
||||
$fileObjects = $fileRepository->findByRelation('tx_odsosm_track', 'file', $item['uid']);
|
||||
if ($fileObjects) {
|
||||
$file = $fileObjects[0];
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
// Add tracks to layerswitcher
|
||||
$this->layers[1][] = [
|
||||
'title' => $item['title'],
|
||||
'table' => $table,
|
||||
'uid' => $item['uid']
|
||||
];
|
||||
|
||||
switch (strtolower(pathinfo($file->getName(), PATHINFO_EXTENSION))) {
|
||||
case 'kml':
|
||||
// include javascript file for KML support
|
||||
$this->scripts['leaflet-plugins'] = [
|
||||
'src' => $this->path_res . 'leaflet-plugins/layer/vector/KML.js'
|
||||
];
|
||||
|
||||
$jsMarker .= 'var ' . $jsElementVar . ' = new L.KML(';
|
||||
$jsMarker .= '"' . $file->getPublicUrl() . '"';
|
||||
$jsMarker .= ");\n";
|
||||
$jsMarker .= $this->config['id'] . '.addLayer(' . $jsElementVar . ');' . "\n";
|
||||
break;
|
||||
case 'gpx':
|
||||
// include javascript file for GPX support
|
||||
$this->scripts['leaflet-gpx'] = [
|
||||
'src' => $this->path_res . 'leaflet-gpx/gpx.js'
|
||||
];
|
||||
$options = [
|
||||
'clickable' => 'false',
|
||||
'polyline_options' => [
|
||||
'color' => $item['color'],
|
||||
'weight' => $item['width'] ?: 1,
|
||||
],
|
||||
'marker_options' => [
|
||||
'startIconUrl' => $this->path_res . 'leaflet-gpx/pin-icon-start.png',
|
||||
'endIconUrl' => $this->path_res . 'leaflet-gpx/pin-icon-end.png',
|
||||
'shadowUrl' => $this->path_res . 'leaflet-gpx/pin-shadow.png',
|
||||
],
|
||||
];
|
||||
$jsMarker .= 'var ' . $jsElementVar . ' = new L.GPX("' . $file->getPublicUrl() . '",';
|
||||
|
||||
$jsMarker .= json_encode($options) . ");\n";
|
||||
$jsMarker .= $this->config['id'] . '.addLayer(' . $jsElementVar . ');' . "\n";
|
||||
break;
|
||||
}
|
||||
$jsElementVarsForPopup[] = $jsElementVar;
|
||||
break;
|
||||
case 'tx_odsosm_vector':
|
||||
// add styles from record if both are set - color and width
|
||||
if (!empty($item['color']) && !empty($item['width'])) {
|
||||
$jsMarker .= 'var myStyle = {
|
||||
"color": "'.$item['color'].'",
|
||||
"weight": '.$item['width'].',
|
||||
"opacity": 1
|
||||
};';
|
||||
} else {
|
||||
$jsMarker .= 'var myStyle = {};';
|
||||
}
|
||||
|
||||
$fileObjects = $fileRepository->findByRelation('tx_odsosm_vector', 'file', $item['uid']);
|
||||
if ($fileObjects) {
|
||||
$file = $fileObjects[0];
|
||||
$filename = Environment::getPublicPath() . '/' . $file->getPublicUrl();
|
||||
$jsMarker .= 'var ' . $jsElementVar . '_file = new L.geoJson(' . file_get_contents($filename) . ',
|
||||
{
|
||||
style: myStyle
|
||||
});' . "\n";
|
||||
$jsMarker .= $this->config['id'] . '.addLayer(' . $jsElementVar . '_file);' . "\n";
|
||||
|
||||
// Add vector file to layerswitcher
|
||||
$this->layers[1][] = [
|
||||
'title' => $item['title'] . ' ('. LocalizationUtility::translate('file', 'OdsOsm') .')',
|
||||
'table' => $table,
|
||||
'uid' => $item['uid'] . '_file'
|
||||
];
|
||||
$jsElementVarsForPopup[] = $jsElementVar . '_file';
|
||||
}
|
||||
|
||||
// add geojson from data field as well
|
||||
if ($item['data']) {
|
||||
$jsMarker .= 'var ' . $jsElementVar . '_data = new L.geoJson(' . $item['data'] . ',
|
||||
{
|
||||
style: myStyle
|
||||
});' . "\n";
|
||||
$jsMarker .= $this->config['id'] . '.addLayer(' . $jsElementVar . '_data);' . "\n";
|
||||
|
||||
// Add vector data to layerswitcher
|
||||
$this->layers[1][] = [
|
||||
'title' => $item['title'],
|
||||
'table' => $table,
|
||||
'uid' => $item['uid'] . '_data'
|
||||
];
|
||||
$jsElementVarsForPopup[] = $jsElementVar . '_data';
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
$markerOptions = [];
|
||||
if ($item['tx_odsosm_marker'] ?? false) {
|
||||
$marker = $item['tx_odsosm_marker'];
|
||||
$iconOptions = [
|
||||
'iconSize' => [(int)$marker['size_x'], (int)$marker['size_y']],
|
||||
'iconAnchor' => [-(int)$marker['offset_x'], -(int)$marker['offset_y']],
|
||||
'popupAnchor' => [0, (int)$marker['offset_y']]
|
||||
];
|
||||
if ($marker['type'] == 'html') {
|
||||
$iconOptions['html'] = $marker['icon'];
|
||||
$markerOptions['icon'] = 'icon: new L.divIcon(' . json_encode($iconOptions) . ')';
|
||||
} else {
|
||||
$icon = $marker['icon']->getPublicUrl();
|
||||
$iconOptions['iconUrl'] = $icon;
|
||||
$markerOptions['icon'] = 'icon: new L.Icon(' . json_encode($iconOptions) . ')';
|
||||
}
|
||||
} else {
|
||||
$marker = [ 'type' => 'image' ];
|
||||
$icon = $this->path_leaflet . 'images/marker-icon.png';
|
||||
}
|
||||
$jsMarker .= 'var ' . $jsElementVar . ' = new L.Marker([' . $item['latitude'] . ', ' . $item['longitude'] . '], {' . implode(',', $markerOptions) . "});\n";
|
||||
// Add group to layer switch
|
||||
if ($item['group_title'] ?? false) {
|
||||
$this->layers[1][] = [
|
||||
'title' => ($marker['type'] == 'html' ? $marker['icon'] : "<img class='marker-icon' src='" . $icon . "' />") . ' ' . $item['group_title'],
|
||||
'gid' => $item['group_uid']
|
||||
];
|
||||
$this->layers[2][$item['group_uid']][] = $jsElementVar;
|
||||
} else {
|
||||
$this->layers[2][$this->config['id'] . '_g'][] = $jsElementVar;
|
||||
}
|
||||
|
||||
$jsElementVarsForPopup[] = $jsElementVar;
|
||||
break;
|
||||
}
|
||||
|
||||
foreach ($jsElementVarsForPopup as $jsElementVar) {
|
||||
// is there a properties attribute from geoJSON? If so, we will show the given properties
|
||||
$popupJsCode = '';
|
||||
if ($item['properties'] ?? null) {
|
||||
$geojsonProperties = json_encode(explode(', ', $item['properties']));
|
||||
$popupJsCode = "
|
||||
function (layer) {
|
||||
var osm_popup = '" . ($item['popup'] ?? '') . "';
|
||||
|
||||
var feature = layer.feature,
|
||||
props = feature.properties,
|
||||
ll = Object.keys(props),
|
||||
attribute, value = '';
|
||||
|
||||
var osm_filter = " . $geojsonProperties . ";
|
||||
|
||||
osm_filter.forEach((osm_prop) => {
|
||||
if (typeof props[osm_prop] !== 'undefined') {
|
||||
value += '<dt>' + osm_prop + '</dt> <dd>' + props[osm_prop] + '</dd>';
|
||||
}
|
||||
});
|
||||
return osm_popup + '<dl>' + value + '</dl>';
|
||||
}
|
||||
";
|
||||
} elseif ($item['popup'] ?? null) {
|
||||
$popupJsCode = json_encode($item['popup'] ?? '');
|
||||
}
|
||||
if ($this->config['show_popups'] == 1) {
|
||||
$jsMarker .= $jsElementVar . '.bindPopup(' . $popupJsCode . '); ' . "\n";
|
||||
if ($item['initial_popup'] ?? null) {
|
||||
$jsMarker .= $jsElementVar . ".openPopup();\n";
|
||||
}
|
||||
} elseif ($this->config['show_popups'] == 2) {
|
||||
$jsMarker .= $jsElementVar . '.bindTooltip(' . $popupJsCode . ");\n";
|
||||
}
|
||||
}
|
||||
|
||||
return $jsMarker;
|
||||
}
|
||||
}
|
||||
632
typo3conf/ext/ods_osm/Classes/Provider/Openlayers.php
Normal file
@@ -0,0 +1,632 @@
|
||||
<?php
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2022 Alexander Bigga <alexander@bigga.de>
|
||||
* All rights reserved
|
||||
*
|
||||
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||
* free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The GNU General Public License can be found at
|
||||
* http://www.gnu.org/copyleft/gpl.html.
|
||||
*
|
||||
* This script is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
namespace Bobosch\OdsOsm\Provider;
|
||||
|
||||
use Bobosch\OdsOsm\Div;
|
||||
use TYPO3\CMS\Core\Page\PageRenderer;
|
||||
use TYPO3\CMS\Core\Resource\FileRepository;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Core\Utility\PathUtility;
|
||||
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
|
||||
|
||||
class Openlayers extends BaseProvider
|
||||
{
|
||||
protected $layers = [
|
||||
0 => [], // Base
|
||||
1 => [], // Overlay
|
||||
2 => [], // Marker
|
||||
];
|
||||
|
||||
public function getMapCore($backpath = ''): void
|
||||
{
|
||||
$path = ($backpath ? $backpath :
|
||||
PathUtility::getAbsoluteWebPath(
|
||||
GeneralUtility::getFileAbsFileName(Div::RESOURCE_BASE_PATH . 'OpenLayers/')
|
||||
)
|
||||
);
|
||||
$pathOl = ($this->config['local_js'] ? $path : 'https://cdn.jsdelivr.net/npm/ol@v8.1.0/');
|
||||
$pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
|
||||
$pageRenderer->addCssFile($pathOl . 'ol.css');
|
||||
$this->scripts['OpenLayers'] = [
|
||||
'src' => $pathOl . 'dist/ol.js',
|
||||
'sri' => 'sha512-7BxMviUlJVAJOF4l717SzPknm3Y5nLAm3PPtRdrWlCu4GLaW+RhBxYuOJ1MkVNAcPu+lRWn4gtWx0PAxvTzD0g=='
|
||||
];
|
||||
|
||||
// Do we need the layerswitcher? If so, some extra plugin is required.
|
||||
if ($this->config['show_layerswitcher']) {
|
||||
$pathContrib = ($this->config['local_js'] ? $path . 'Contrib/ol-layerswitcher/' : 'https://unpkg.com/ol-layerswitcher@4.1.1/dist/');
|
||||
$pathCustom = $path . 'Custom/';
|
||||
|
||||
$pageRenderer->addCssFile($pathContrib . 'ol-layerswitcher.css');
|
||||
$pageRenderer->addCssFile($pathCustom . 'ol-layerswitcher.css');
|
||||
|
||||
$this->scripts['OpenLayersSwitch'] = [
|
||||
'src' => $pathContrib . 'ol-layerswitcher.js',
|
||||
'sri' => 'sha512-HhCrrWOoQb5HSpRe1fsk9ugZQEOokbJsLioPuUhfXlr5ccRTZVg3UpnfRsTJzrdKLejmx7uvY62n2fp5qLdYQg=='
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
public function getMapMain()
|
||||
{
|
||||
$controls = [
|
||||
'new ol.control.Attribution()',
|
||||
'new ol.control.Zoom()',
|
||||
'new ol.control.Rotate()'
|
||||
];
|
||||
if ($this->config['mouse_position']) {
|
||||
$controls[] = "new ol.control.MousePosition({
|
||||
coordinateFormat: ol.coordinate.createStringXY(2),
|
||||
projection: 'EPSG:4326',
|
||||
className: 'ods-osm-mouse-position',
|
||||
target: document.getElementById('mouse-position-" . $this->config['id'] . "')
|
||||
})";
|
||||
}
|
||||
if ($this->config['show_scalebar']) {
|
||||
$controls[] = "new ol.control.ScaleLine()";
|
||||
}
|
||||
|
||||
return "
|
||||
view = new ol.View({
|
||||
center: [0, 0],
|
||||
zoom: 1
|
||||
});
|
||||
|
||||
baselayergroup = new ol.layer.Group({
|
||||
name: 'baselayergroup',
|
||||
title: '" . LocalizationUtility::translate('base_layer', 'OdsOsm') . "',
|
||||
layers: [
|
||||
new ol.layer.Tile({
|
||||
type: 'base',
|
||||
source: new ol.source.OSM(),
|
||||
})
|
||||
]
|
||||
});
|
||||
|
||||
overlaygroup = new ol.layer.Group({
|
||||
name: 'overlaygroup',
|
||||
title: '" . LocalizationUtility::translate('overlays', 'OdsOsm') . "',
|
||||
layers: []
|
||||
});
|
||||
|
||||
const styleCache = {};
|
||||
clusters = new ol.layer.Vector({
|
||||
name: 'clusters',
|
||||
title: '" . LocalizationUtility::translate('openlayers.clusterLayer', 'OdsOsm') . "',
|
||||
source: new ol.source.Cluster({
|
||||
distance: " . (int)$this->config['cluster_radius'] . ",
|
||||
minDistance: 10,
|
||||
source: new ol.source.Vector({
|
||||
name: 'source',
|
||||
features: [],
|
||||
})
|
||||
}),
|
||||
style: function (feature) {
|
||||
const size = feature.get('features').length;
|
||||
if (size > 1) {
|
||||
style = new ol.style.Style({
|
||||
image: new ol.style.Circle({
|
||||
radius: 20,
|
||||
stroke: new ol.style.Stroke({
|
||||
color: '#fff',
|
||||
}),
|
||||
fill: new ol.style.Fill({
|
||||
color: '#3399CC',
|
||||
}),
|
||||
}),
|
||||
text: new ol.style.Text({
|
||||
text: size.toString(),
|
||||
fill: new ol.style.Fill({
|
||||
color: '#fff',
|
||||
}),
|
||||
}),
|
||||
});
|
||||
} else {
|
||||
style = feature.get('features')[0].values_.style;
|
||||
}
|
||||
return style;
|
||||
},
|
||||
});
|
||||
|
||||
layers = [
|
||||
baselayergroup,
|
||||
overlaygroup
|
||||
];
|
||||
|
||||
var " . $this->config['id'] . " = new ol.Map({
|
||||
target: '" . $this->config['id'] . "',
|
||||
controls:[" . implode(',', $controls) . "],
|
||||
layers: layers,
|
||||
view: view
|
||||
});
|
||||
|
||||
// Popup showing the position the user clicked
|
||||
var container = document.getElementById('popup');
|
||||
var closer = document.getElementById('popup-closer');
|
||||
var content = document.getElementById('popup-content');
|
||||
var popup = new ol.Overlay({
|
||||
element: container,
|
||||
autoPan: true,
|
||||
autoPanAnimation: {
|
||||
duration: 100
|
||||
}
|
||||
});
|
||||
" . $this->config['id'] . ".addOverlay(popup);
|
||||
closer.onclick = function () {
|
||||
popup.setPosition(undefined);
|
||||
content.innerHTML = '';
|
||||
closer.blur();
|
||||
return false;
|
||||
};
|
||||
";
|
||||
}
|
||||
|
||||
/**
|
||||
* The center and zoom level of the map
|
||||
*
|
||||
* @param float $lat: latitude
|
||||
* @param float $lon: longitude
|
||||
* @param int $zoom: zoom level
|
||||
*
|
||||
* @return string The JavaScript to set the center and zoom level
|
||||
*/
|
||||
public function getMapCenter($lat, $lon, $zoom)
|
||||
{
|
||||
return '
|
||||
view.setCenter(ol.proj.transform([' . $lon . ', ' . $lat . '], \'EPSG:4326\', \'EPSG:3857\'));
|
||||
view.setZoom(' . $zoom . ');
|
||||
';
|
||||
}
|
||||
|
||||
protected function getLayer($layer, $i, $backpath = '')
|
||||
{
|
||||
if (empty($layer['subdomains'])) {
|
||||
$layer['subdomains'] = 'abc';
|
||||
}
|
||||
$layer['subdomains'] = substr($layer['subdomains'], 0, 1) . '-' . substr($layer['subdomains'], -1, 1);
|
||||
$layer['tile_url'] = strtr($this->getTileUrl($layer), ['{s}' => '{' . $layer['subdomains'] . '}']);
|
||||
|
||||
if ($layer['overlay'] == 1) {
|
||||
return $this->config['id'] . "_" . $i . "_overlayLayer =
|
||||
new ol.layer.Tile({
|
||||
visible: " . ($layer['visible'] == true ? 'true' : 'false') . ",
|
||||
opacity: 0.99,
|
||||
title: '" . $layer['title'] . "',
|
||||
source: new ol.source.OSM({
|
||||
url: '" . $layer['tile_url'] . "',
|
||||
attributions: [
|
||||
'" . $layer['attribution']. "'
|
||||
]
|
||||
})
|
||||
});
|
||||
overlaygroup.getLayers().push(" . $this->config['id'] . "_" . $i . "_overlayLayer);
|
||||
";
|
||||
}
|
||||
|
||||
return $this->config['id'] . "_" . $i . "_baselayergroup =
|
||||
new ol.layer.Tile({
|
||||
type: 'base',
|
||||
combine: 'true',
|
||||
visible: " . ($i == 0 ? 'true' : 'false') . ",
|
||||
title: '" . $layer['title'] . "',
|
||||
source: new ol.source.OSM({
|
||||
url: '" . $layer['tile_url'] . "',
|
||||
attributions: [
|
||||
'" . $layer['attribution']. "'
|
||||
]
|
||||
})
|
||||
});
|
||||
baselayergroup.getLayers().push(" . $this->config['id'] . "_" . $i . "_baselayergroup);
|
||||
";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the layer switcher
|
||||
*
|
||||
* @return string The JavaScript to add the layerswitcher
|
||||
*/
|
||||
protected function getLayerSwitcher()
|
||||
{
|
||||
return '
|
||||
var layerSwitcher = new ol.control.LayerSwitcher({
|
||||
activationMode: \'' . ($this->config['layerswitcher_activationMode'] == '1' ? 'click' : 'mouseover') . '\',
|
||||
startActive: ' . ($this->config['show_layerswitcher'] == '2' ? 'true' : 'false') . ',
|
||||
tipLabel: \'' . LocalizationUtility::translate('openlayers.showLayerList', 'OdsOsm') . '\',
|
||||
collapseTipLabel: \'' . LocalizationUtility::translate('openlayers.hideLayerList', 'OdsOsm') . '\',
|
||||
groupSelectStyle: \'children\',
|
||||
reverse: false
|
||||
});
|
||||
' . $this->config['id'] . '.addControl(layerSwitcher);
|
||||
';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the fullscreen button
|
||||
*
|
||||
* @return string The JavaScript to add the fullscreen button
|
||||
*/
|
||||
protected function getFullScreen()
|
||||
{
|
||||
return '
|
||||
var fullScreen = new ol.control.FullScreen();
|
||||
' . $this->config['id'] . '.addControl(fullScreen);
|
||||
';
|
||||
}
|
||||
|
||||
protected function getMarkers($markers)
|
||||
{
|
||||
$jsMarker = parent::getMarkers($markers);
|
||||
|
||||
// open popup? If yes, with click or hover?
|
||||
switch ($this->config['show_popups']) {
|
||||
case 1:
|
||||
$eventMethod = 'singleclick';
|
||||
break;
|
||||
case 2:
|
||||
$eventMethod = 'pointermove';
|
||||
break;
|
||||
default:
|
||||
$eventMethod = false;
|
||||
}
|
||||
|
||||
if ($eventMethod !== false) {
|
||||
$jsMarker .= "
|
||||
" . $this->config['id'] . ".on('" . $eventMethod . "', function (event) {
|
||||
var feature = " . $this->config['id'] . ".forEachFeatureAtPixel(event.pixel, function (feat, layer) {
|
||||
return feat;
|
||||
});
|
||||
var layer = " . $this->config['id'] . ".forEachFeatureAtPixel(event.pixel, function (feat, layer) {
|
||||
return layer;
|
||||
});
|
||||
|
||||
if (feature === undefined) {
|
||||
return;
|
||||
}
|
||||
if (feature.get('features') === undefined) {
|
||||
var coordinate = event.coordinate;
|
||||
if (feature.get('desc') !== undefined) {
|
||||
content.innerHTML = feature.get('desc');
|
||||
} else {
|
||||
// this might be some geoJSON data with properties set
|
||||
|
||||
var osm_popup = layer.get('popup');
|
||||
var props = feature.values_,
|
||||
ll = Object.keys(props),
|
||||
attribute, value = '';
|
||||
|
||||
var osm_filter = layer.get('properties').split(',').map(item=>item.trim());
|
||||
|
||||
osm_filter.forEach((osm_prop) => {
|
||||
if (typeof feature.get(osm_prop) !== 'undefined') {
|
||||
value += '<dt>' + osm_prop + '</dt> <dd>' + feature.get(osm_prop) + '</dd>';
|
||||
}
|
||||
});
|
||||
content.innerHTML = osm_popup + '<dl>' + value + '</dl>';
|
||||
}
|
||||
popup.setPosition(coordinate);
|
||||
} else if (feature.get('features').length === 1) {
|
||||
var singleFeature = feature.get('features')[0];
|
||||
if (feature && singleFeature.get('type') == 'Point') {
|
||||
var coordinate = event.coordinate;
|
||||
|
||||
content.innerHTML = singleFeature.get('desc');
|
||||
popup.setPosition(coordinate);
|
||||
}
|
||||
} else if (feature && feature.get('type') == 'Point') {
|
||||
|
||||
var coordinate = event.coordinate;
|
||||
|
||||
content.innerHTML = feature.get('desc');
|
||||
popup.setPosition(coordinate);
|
||||
} else {
|
||||
if (feature.get('features').length > 0) {
|
||||
const clusterMembers = feature.get('features');
|
||||
if (clusterMembers.length > 1) {
|
||||
// Calculate the extent of the cluster members.
|
||||
const extent = new ol.extent.createEmpty();
|
||||
clusterMembers.forEach((feature) =>
|
||||
ol.extent.extend(extent, feature.getGeometry().getExtent())
|
||||
);
|
||||
const view = " . $this->config['id'] . ".getView();
|
||||
const resolution = " . $this->config['id'] . ".getView().getResolution();
|
||||
if (
|
||||
view.getZoom() === view.getMaxZoom() ||
|
||||
(ol.extent.getWidth(extent) < resolution && ol.extent.getHeight(extent) < resolution)
|
||||
) {
|
||||
// Show an expanded view of the cluster members.
|
||||
clickFeature = features[0];
|
||||
clickResolution = resolution;
|
||||
clusterCircles.setStyle(clusterCircleStyle);
|
||||
} else {
|
||||
// Zoom to the extent of the cluster members.
|
||||
view.fit(extent, {duration: 600, padding: [100, 100, 100, 100]});
|
||||
}
|
||||
}
|
||||
}
|
||||
popup.setPosition(undefined);
|
||||
}
|
||||
});
|
||||
";
|
||||
}
|
||||
|
||||
// grouped marker layer
|
||||
foreach ($this->layers[2] as $group_uid => $group) {
|
||||
|
||||
$jsMarker .= $group['layer'];
|
||||
$jsMarkerFeatureBatch = [];
|
||||
foreach ($group['jsMarkerFeatures'] as $id => $jsMarkerFeature) {
|
||||
$jsMarker .= 'var ' . $group_uid . $id . ' = ' . $jsMarkerFeature;
|
||||
$jsMarkerFeatureBatch[] = $group_uid . $id;
|
||||
}
|
||||
|
||||
if ($this->config['cluster']) {
|
||||
$jsMarker .= 'clusters.getSource().getSource().addFeatures([' . implode(',', $jsMarkerFeatureBatch) . ']);' . "\n";
|
||||
} else {
|
||||
$jsMarker .= $group_uid . '.getSource().addFeatures([' . implode(',', $jsMarkerFeatureBatch) . ']);' . "\n";
|
||||
$jsMarker .= 'overlaygroup.getLayers().push(' . $group_uid . ');' . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->config['cluster']) {
|
||||
// add cluster layer in overlaygroup
|
||||
$jsMarker .= 'overlaygroup.getLayers().push(clusters);' . "\n";
|
||||
}
|
||||
|
||||
return $jsMarker;
|
||||
}
|
||||
|
||||
protected function getMarker($item, $table)
|
||||
{
|
||||
$jsMarker = '';
|
||||
$jsElementVar = $table . '_' . $item['uid'];
|
||||
$fileRepository = GeneralUtility::makeInstance(FileRepository::class);
|
||||
|
||||
// Convert item color hex value to rgba() as Openlayers doesn't have an opacity option.
|
||||
if (empty($item['color'])) {
|
||||
// set default blue, if nothing is given
|
||||
$item['color'] = '#0009ff';
|
||||
}
|
||||
if (strlen($item['color']) == 7) {
|
||||
$hex = [ $item['color'][1] . $item['color'][2], $item['color'][3] . $item['color'][4], $item['color'][5] . $item['color'][6] ];
|
||||
$rgb = array_map('hexdec', $hex);
|
||||
$opacity = '0.2';
|
||||
$item['rgba'] = 'rgba('.implode(",", $rgb).','.$opacity.')';
|
||||
}
|
||||
|
||||
switch ($table) {
|
||||
case 'tx_odsosm_track':
|
||||
$fileObjects = $fileRepository->findByRelation('tx_odsosm_track', 'file', $item['uid']);
|
||||
if ($fileObjects) {
|
||||
$file = $fileObjects[0];
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
// Add tracks to layerswitcher
|
||||
$this->layers[1][] = [
|
||||
'title' => $item['title'],
|
||||
'table' => $table,
|
||||
'uid' => $item['uid']
|
||||
];
|
||||
|
||||
// define style from given color and width
|
||||
$jsMarker .= 'var ' . $jsElementVar . '_style = new ol.style.Style({
|
||||
stroke: new ol.style.Stroke({
|
||||
color: \''.$item['color'].'\',
|
||||
width: '.($item['width'] ?: 1).'
|
||||
}),
|
||||
fill: new ol.style.Fill({
|
||||
color: \''.$item['rgba'].'\'
|
||||
}),
|
||||
});';
|
||||
|
||||
switch (strtolower(pathinfo($file->getName(), PATHINFO_EXTENSION))) {
|
||||
case 'kml':
|
||||
$jsMarker .= 'var ' . $jsElementVar . '_gpx = new ol.layer.Vector({
|
||||
title: \'' .$item['title'] . '\',
|
||||
source: new ol.source.Vector({
|
||||
projection: \'EPSG:3857\',
|
||||
url: \'' . $file->getPublicUrl() . '\',
|
||||
format: new ol.format.KML()
|
||||
}),
|
||||
style: ' . $jsElementVar . '_style
|
||||
});' . "\n";
|
||||
|
||||
$jsMarker .= "overlaygroup.getLayers().push(" . $jsElementVar . "_gpx);";
|
||||
break;
|
||||
case 'gpx':
|
||||
$jsMarker .= 'var ' . $jsElementVar . '_gpx = new ol.layer.Vector({
|
||||
title: \'' .$item['title'] . '\',
|
||||
source: new ol.source.Vector({
|
||||
projection: \'EPSG:3857\',
|
||||
url: \'' . $file->getPublicUrl() . '\',
|
||||
format: new ol.format.GPX()
|
||||
}),
|
||||
style: ' . $jsElementVar . '_style
|
||||
});' . "\n";
|
||||
|
||||
$jsMarker .= "overlaygroup.getLayers().push(" . $jsElementVar . "_gpx);";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'tx_odsosm_vector':
|
||||
$fileObjects = $fileRepository->findByRelation('tx_odsosm_vector', 'file', $item['uid']);
|
||||
|
||||
// define style from given color and width
|
||||
$jsMarker .= 'var ' . $jsElementVar . '_style = new ol.style.Style({
|
||||
stroke: new ol.style.Stroke({
|
||||
color: \''.$item['color'].'\',
|
||||
width: '.($item['width'] ?: 1).'
|
||||
}),
|
||||
fill: new ol.style.Fill({
|
||||
color: \''.$item['rgba'].'\'
|
||||
}),
|
||||
});' . "\n";
|
||||
|
||||
if ($fileObjects) {
|
||||
$file = $fileObjects[0];
|
||||
$filename = $file->getPublicUrl();
|
||||
|
||||
$properties = [
|
||||
'popup' => $item['popup'] ?? '',
|
||||
'properties' => $item['properties'],
|
||||
];
|
||||
|
||||
$jsMarker .= 'var ' . $jsElementVar . '_file_properties = ' . json_encode($properties) . ';';
|
||||
$jsMarker .= 'var ' . $jsElementVar . '_file = new ol.layer.Vector({
|
||||
title: \'' .$item['title'] . ' ('. LocalizationUtility::translate('file', 'OdsOsm') .')\',
|
||||
source: new ol.source.Vector({
|
||||
projection: \'EPSG:3857\',
|
||||
url: \'' . $filename . '\',
|
||||
format: new ol.format.GeoJSON()
|
||||
}),
|
||||
style: ' . $jsElementVar . '_style,
|
||||
properties: ' . $jsElementVar . '_file_properties,
|
||||
});' . "\n";
|
||||
|
||||
$jsMarker .= $jsElementVar . "_file.getSource().setProperties(" . $jsElementVar . "_file_properties);";
|
||||
$jsMarker .= "overlaygroup.getLayers().push(" . $jsElementVar . "_file);";
|
||||
}
|
||||
|
||||
// add geojson from data field as well
|
||||
if ($item['data']) {
|
||||
$properties = [
|
||||
'popup' => $item['popup'] ? $item['popup'] . '<br />' : '',
|
||||
'properties' => $item['properties'],
|
||||
];
|
||||
|
||||
$jsMarker .= 'const ' . $jsElementVar . '_geojsonObject = '. $item['data'] . ';';
|
||||
|
||||
$jsMarker .= 'var ' . $jsElementVar . '_data_properties = ' . json_encode($properties) . ';';
|
||||
$jsMarker .= 'var ' . $jsElementVar . '_data = new ol.layer.Vector({
|
||||
title: \'' .$item['title'] . '\',
|
||||
source: new ol.source.Vector({
|
||||
features: new ol.format.GeoJSON({
|
||||
featureProjection:"EPSG:3857"
|
||||
}).readFeatures(' . $jsElementVar . '_geojsonObject)
|
||||
}),
|
||||
style: ' . $jsElementVar . '_style
|
||||
});';
|
||||
|
||||
$jsMarker .= $jsElementVar . "_data.setProperties(" . $jsElementVar . "_data_properties);";
|
||||
$jsMarker .= "overlaygroup.getLayers().push(" . $jsElementVar . "_data);";
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
$markerOptions = [];
|
||||
if ($item['tx_odsosm_marker'] ?? false) {
|
||||
$marker = $item['tx_odsosm_marker'];
|
||||
if ($marker['type'] == 'html') {
|
||||
$markerOptions['icon'] = 'icon: new L.divIcon(' . json_encode($marker['icon']) . ')';
|
||||
} else {
|
||||
$icon = $marker['icon']->getPublicUrl();
|
||||
$markerOptions['icon'] = 'icon: new L.Icon(' . json_encode($icon) . ')';
|
||||
}
|
||||
} else {
|
||||
$icon = '/typo3conf/ext/ods_osm/Resources/Public/Icons/marker-icon.png';
|
||||
$marker['size_x'] = 25;
|
||||
$marker['size_y'] = 41;
|
||||
}
|
||||
|
||||
$markerStyle = "const " . $jsElementVar . "_style = new ol.style.Style({
|
||||
image: new ol.style.Icon({
|
||||
anchor: [0.5, 46],
|
||||
anchorXUnits: 'fraction',
|
||||
anchorYUnits: 'pixels',
|
||||
src: '" . $icon ."',
|
||||
width: " . (int)$marker['size_x'] . ",
|
||||
height: " . (int)$marker['size_y'] . "
|
||||
}),
|
||||
});";
|
||||
|
||||
// It's a group of markers
|
||||
if ($item['group_title'] ?? false) {
|
||||
if (empty($jsMarkerGroup)) {
|
||||
$jsMarker .= $markerStyle;
|
||||
|
||||
$group_title = ($marker['type'] == 'html' ? $icon : "<img class='marker-icon' src='" . $icon . "' />") . ' ' . $item['group_title'];
|
||||
$jsMarkerGroup = "
|
||||
var " . $item['group_uid'] . " = new ol.layer.Vector({
|
||||
title: \"" . $group_title . "\",
|
||||
source: new ol.source.Vector({
|
||||
features: []
|
||||
}),
|
||||
style: " . $jsElementVar . "_style
|
||||
});";
|
||||
|
||||
$this->layers[2][$item['group_uid']]['layer'] = $jsMarkerGroup;
|
||||
}
|
||||
|
||||
$popupJsCode = "
|
||||
function (layer) {
|
||||
var osm_popup = '" . ($item['popup'] ?? '') . "';
|
||||
|
||||
var feature = layer.feature,
|
||||
props = feature.properties,
|
||||
ll = Object.keys(props),
|
||||
attribute, value = '';
|
||||
|
||||
for (attribute in props) {
|
||||
value += '<strong>' + attribute + '</strong>: ' + props[attribute] + '<br />';
|
||||
}
|
||||
return osm_popup + value;
|
||||
}
|
||||
";
|
||||
|
||||
$jsMarkerFeature = "
|
||||
new ol.Feature({
|
||||
geometry: new ol.geom.Point(ol.proj.fromLonLat([" . $item['longitude'] . ", " . $item['latitude'] . "])),
|
||||
type: 'Point',
|
||||
desc: " . json_encode($item['popup']) . ",
|
||||
style: " . $jsElementVar . "_style
|
||||
});";
|
||||
|
||||
$this->layers[2][$item['group_uid']]['jsMarkerFeatures'][] = $jsMarkerFeature;
|
||||
} else {
|
||||
$jsMarker .= $markerStyle;
|
||||
$jsMarker .= "var " . $jsElementVar . " = new ol.layer.Vector({
|
||||
title: '<img src=\"" .$icon . "\" class=\"marker-icon\" /> " . ($item['group_title'] ?? $item['name']) . "',
|
||||
source: new ol.source.Vector({
|
||||
features: [
|
||||
new ol.Feature({
|
||||
geometry: new ol.geom.Point(ol.proj.fromLonLat([" . $item['longitude'] . ", " . $item['latitude'] . "])),
|
||||
type: 'Point',
|
||||
desc: " . json_encode($item['popup']) . "
|
||||
})
|
||||
]
|
||||
}),
|
||||
style: " . $jsElementVar . "_style
|
||||
});";
|
||||
|
||||
$jsMarker .= 'overlaygroup.getLayers().push(' . $jsElementVar . ');' . "\n";
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return $jsMarker;
|
||||
}
|
||||
}
|
||||
108
typo3conf/ext/ods_osm/Classes/Provider/Staticmap.php
Normal file
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
namespace Bobosch\OdsOsm\Provider;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Core\Core\Environment;
|
||||
|
||||
class Staticmap extends BaseProvider
|
||||
{
|
||||
protected $uploadPath = 'fileadmin/tx_odsosm/staticmap';
|
||||
|
||||
public function getMap($layers, $markers, $lon, $lat, $zoom)
|
||||
{
|
||||
$marker = [];
|
||||
|
||||
foreach ($markers as $table => $items) {
|
||||
foreach ($items as $item) {
|
||||
switch ($table) {
|
||||
case 'tx_odsosm_track':
|
||||
case 'tx_odsosm_vector':
|
||||
break;
|
||||
default:
|
||||
$lon = $item['longitude'];
|
||||
$lat = $item['latitude'];
|
||||
if ($item['tx_odsosm_marker'] ?? false) {
|
||||
$marker = $item['tx_odsosm_marker'];
|
||||
$icon = $marker['icon'];
|
||||
} else {
|
||||
$marker = ['size_x' => 21, 'size_y' => 25, 'offset_x' => -11, 'offset_y' => -25];
|
||||
$icon = 'EXT:ods_osm/Resources/Public/Icons/marker-icon.png';
|
||||
}
|
||||
break 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set reasonable defaults for width and height (100% and vh/vw does not work with staticmap)
|
||||
if ((int)$this->config['width'] <= 100) {
|
||||
$this->config['width'] = 640;
|
||||
}
|
||||
if ((int)$this->config['height'] <= 100) {
|
||||
$this->config['height'] = 480;
|
||||
}
|
||||
|
||||
|
||||
$markerUrl = [
|
||||
'###lon###' => $lon,
|
||||
'###lat###' => $lat,
|
||||
'###zoom###' => $zoom,
|
||||
'###width###' => (int)$this->config['width'],
|
||||
'###height###' => (int)$this->config['height'],
|
||||
];
|
||||
|
||||
$layer = array_shift($layers);
|
||||
$url = strtr($layer[0]['static_url'], $markerUrl);
|
||||
|
||||
$this->uploadPath = Environment::getPublicPath() . '/' . $this->uploadPath;
|
||||
if (!is_dir($this->uploadPath)) {
|
||||
GeneralUtility::mkdir_deep($this->uploadPath);
|
||||
}
|
||||
|
||||
$filename = $this->uploadPath . '/' . md5($url) . '.png';
|
||||
|
||||
// Cache image
|
||||
$cache = false;
|
||||
if (file_exists($filename)) {
|
||||
$cache = filectime($filename) > time() - 7 * 24 * 60 * 60;
|
||||
}
|
||||
if (!$cache) {
|
||||
$referer = $_SERVER['HTTP_REFERER'];
|
||||
$opts = [
|
||||
'http'=>[
|
||||
'header'=>["Referer: $referer\r\n"]
|
||||
]
|
||||
];
|
||||
$context = stream_context_create($opts);
|
||||
$image = file_get_contents($url, false, $context);
|
||||
if ($image) {
|
||||
file_put_contents($filename, $image);
|
||||
}
|
||||
}
|
||||
|
||||
// Generate image tag
|
||||
$config = [
|
||||
'file' => 'GIFBUILDER',
|
||||
'file.' => [
|
||||
'format' => 'png',
|
||||
'XY' => '[10.w],[10.h]',
|
||||
'10' => 'IMAGE',
|
||||
'10.' => [
|
||||
'file' => $filename,
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
if ($marker['offset_x'] ?? null) {
|
||||
$config['file.']['20'] = 'IMAGE';
|
||||
$config['file.']['20.'] = [
|
||||
'offset' => ((int)$this->config['width'] / 2 + (int)$marker['offset_x']) . ',' . ((int)$this->config['height'] / 2 + (int)$marker['offset_y']),
|
||||
'file' => $icon,
|
||||
];
|
||||
}
|
||||
|
||||
$content = $this->cObj->cObjGetSingle('IMAGE', $config);
|
||||
|
||||
return ($content);
|
||||
}
|
||||
}
|
||||
365
typo3conf/ext/ods_osm/Classes/TceMain.php
Normal file
@@ -0,0 +1,365 @@
|
||||
<?php
|
||||
|
||||
namespace Bobosch\OdsOsm;
|
||||
|
||||
use TYPO3\CMS\Core\DataHandling\DataHandler;
|
||||
use \geoPHP\geoPHP;
|
||||
use TYPO3\CMS\Core\Core\Environment;
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Resource\FileRepository;
|
||||
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
class TceMain
|
||||
{
|
||||
public $lon = [];
|
||||
public $lat = [];
|
||||
|
||||
// ['t3lib/class.t3lib_tcemain.php']['processDatamapClass']
|
||||
public function processDatamap_preProcessFieldArray(&$incomingFieldArray, $table, $id, $obj)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a different preview link *
|
||||
*
|
||||
* @param string $status status
|
||||
* @param string $table table name
|
||||
* @param int $id id of the record
|
||||
* @param array $fieldArray fieldArray
|
||||
* @param DataHandler $parentObject parent Object
|
||||
*/
|
||||
public function processDatamap_afterDatabaseOperations(
|
||||
$status,
|
||||
$table,
|
||||
$id,
|
||||
array $fieldArray,
|
||||
DataHandler $parentObject
|
||||
): void {
|
||||
// guard statement, abort here if no ods_osm table
|
||||
if (strpos($table, 'tx_odsosm_') !== 0) {
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* The id may be integer already or the temporary NEW id. This depends, how the record was created
|
||||
*
|
||||
* case 1:
|
||||
* - the user creates a tx_odsosm_track record
|
||||
* - the file is added to the not yet saved record
|
||||
* - the record is saved (status="new")
|
||||
*
|
||||
* case 2:
|
||||
* - the user creates a tx_odsosm_track record and saves it
|
||||
* - the user remains in the dialog and adds the file
|
||||
* - the user saves again (status="update")
|
||||
*
|
||||
* This hook is run for sys_file_reference and for tx_odsosm_track. We only do our work on tx_odsosm_track:
|
||||
* - in case 1 --> id is not integer yet but the temporary NEW id
|
||||
* - in case 2 --> id is integer
|
||||
*/
|
||||
|
||||
if ($status == "new") {
|
||||
$id = $parentObject->substNEWwithIDs[$id] ?? '';
|
||||
}
|
||||
|
||||
if (!is_int($id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If ods_osm is installed via composer, the class geoPHP is already known.
|
||||
* Otherwise we use the copy in the local folder which is only available in the TER package.
|
||||
*/
|
||||
if (!class_exists(geoPHP::class)) {
|
||||
require_once 'phar://' . ExtensionManagementUtility::extPath('ods_osm', 'Resources/Private/geophp.phar/vendor/autoload.php');
|
||||
}
|
||||
|
||||
switch ($table) {
|
||||
case 'tx_odsosm_track':
|
||||
if (is_int($id)) {
|
||||
$fileRepository = GeneralUtility::makeInstance(FileRepository::class);
|
||||
$fileObjects = $fileRepository->findByRelation('tx_odsosm_track', 'file', $id);
|
||||
}
|
||||
if ($fileObjects) {
|
||||
$file = $fileObjects[0];
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
$filename = Environment::getPublicPath() . '/' . $file->getPublicUrl();
|
||||
if (file_exists($filename)) {
|
||||
try {
|
||||
$polygon = geoPHP::load(file_get_contents($filename), pathinfo($filename, PATHINFO_EXTENSION));
|
||||
} catch (\Exception $e) {
|
||||
// silently ignore failure of parsing data
|
||||
break;
|
||||
}
|
||||
$box = $polygon->getBBox();
|
||||
|
||||
// unfortunately we cannot pass the new values by reference in this hook, because the database operation is already done.
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
->getQueryBuilderForTable($table);
|
||||
$queryBuilder
|
||||
->update('tx_odsosm_track')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq('uid', $id)
|
||||
)
|
||||
->set('min_lon', sprintf('%01.6f', $box['minx']))
|
||||
->set('min_lat', sprintf('%01.6f', $box['miny']))
|
||||
->set('max_lon', sprintf('%01.6f', $box['maxx']))
|
||||
->set('max_lat', sprintf('%01.6f', $box['maxy']))
|
||||
->executeStatement();
|
||||
}
|
||||
break;
|
||||
case 'tx_odsosm_marker':
|
||||
if (is_int($id)) {
|
||||
$fileRepository = GeneralUtility::makeInstance(FileRepository::class);
|
||||
$fileObjects = $fileRepository->findByRelation('tx_odsosm_marker', 'icon', $id);
|
||||
}
|
||||
if ($fileObjects) {
|
||||
$file = $fileObjects[0];
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
$filename = Environment::getPublicPath() . '/' . $file->getPublicUrl();
|
||||
if (file_exists($filename)) {
|
||||
$size = getimagesize($filename);
|
||||
|
||||
if ($size) {
|
||||
// unfortunately we cannot pass the new values by reference in this hook, because the database operation is already done.
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
->getQueryBuilderForTable($table);
|
||||
$queryBuilder
|
||||
->update('tx_odsosm_marker')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq('uid', $id)
|
||||
)
|
||||
->set('size_x', $size[0])
|
||||
->set('size_y', $size[1])
|
||||
->set('offset_x', -round($size[0] / 2))
|
||||
->set('offset_y', -$size[1])
|
||||
->executeStatement();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'tx_odsosm_vector':
|
||||
if (is_int($id)) {
|
||||
$fileRepository = GeneralUtility::makeInstance(FileRepository::class);
|
||||
$fileObjects = $fileRepository->findByRelation('tx_odsosm_vector', 'file', $id);
|
||||
}
|
||||
if ($fileObjects) {
|
||||
$file = $fileObjects[0];
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
$filename = Environment::getPublicPath() . '/' . $file->getPublicUrl();
|
||||
if (file_exists($filename)) {
|
||||
|
||||
try {
|
||||
$polygon = geoPHP::load(file_get_contents($filename), pathinfo($filename, PATHINFO_EXTENSION));
|
||||
} catch (\Exception $e) {
|
||||
// silently ignore failure of parsing geojson
|
||||
break;
|
||||
}
|
||||
|
||||
$box = $polygon->getBBox();
|
||||
if ($box) {
|
||||
// unfortunately we cannot pass the new values by reference in this hook, because the database operation is already done.
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
->getQueryBuilderForTable($table);
|
||||
|
||||
// write the bbox into database
|
||||
$queryBuilder
|
||||
->update('tx_odsosm_vector')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq('uid', $id)
|
||||
)
|
||||
->set('min_lon', sprintf('%01.6f', $box['minx']))
|
||||
->set('min_lat', sprintf('%01.6f', $box['miny']))
|
||||
->set('max_lon', sprintf('%01.6f', $box['maxx']))
|
||||
->set('max_lat', sprintf('%01.6f', $box['maxy']))
|
||||
->executeStatement();
|
||||
|
||||
// handle properties
|
||||
$properties = (array)$polygon->getData();
|
||||
if (empty($properties)) {
|
||||
// seems to contain multiple polygones
|
||||
$components = $polygon->getComponents();
|
||||
// take the properties of the first polygon
|
||||
$properties = (array)$components[0]->getData();
|
||||
}
|
||||
|
||||
if (!empty($properties)) {
|
||||
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
->getQueryBuilderForTable($table);
|
||||
|
||||
$result = $queryBuilder
|
||||
->select('properties', 'properties_from_file')
|
||||
->from('tx_odsosm_vector')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq('uid', $id)
|
||||
)
|
||||
->setMaxResults(1)
|
||||
->executeQuery();
|
||||
|
||||
if ($row = $result->fetchAssociative()) {
|
||||
if ($row['properties_from_file'] && !empty($properties)) {
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
->getQueryBuilderForTable($table);
|
||||
|
||||
$queryBuilder
|
||||
->update('tx_odsosm_vector')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq('uid', $id)
|
||||
)
|
||||
->set('properties', implode(', ', array_keys($properties)))
|
||||
->set('properties_from_file', 0)
|
||||
->executeStatement();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ['t3lib/class.t3lib_tcemain.php']['processDatamapClass']
|
||||
public function processDatamap_postProcessFieldArray($status, $table, $id, &$fieldArray, $obj): void
|
||||
{
|
||||
switch ($table) {
|
||||
case 'tx_odsosm_vector':
|
||||
if (!empty($fieldArray['data'] ?? false)) {
|
||||
$this->lon = [];
|
||||
$this->lat = [];
|
||||
|
||||
/*
|
||||
* If ods_osm is installed via composer, the class geoPHP is already known.
|
||||
* Otherwise we use the copy in the local folder which is only available in the TER package.
|
||||
*/
|
||||
if (!class_exists(geoPHP::class)) {
|
||||
require_once 'phar://' . ExtensionManagementUtility::extPath('ods_osm', 'Resources/Private/geophp.phar/vendor/autoload.php');
|
||||
}
|
||||
|
||||
try {
|
||||
$polygon = geoPHP::load(($fieldArray['data']));
|
||||
} catch (\Exception $e) {
|
||||
// silently ignore failure of parsing geojson
|
||||
break;
|
||||
}
|
||||
|
||||
if ($polygon) {
|
||||
$box = $polygon->getBBox();
|
||||
|
||||
$fieldArray['min_lon'] = sprintf('%01.6f', $box['minx']);
|
||||
$fieldArray['min_lat'] = sprintf('%01.6f', $box['miny']);
|
||||
$fieldArray['max_lon'] = sprintf('%01.6f', $box['maxx']);
|
||||
$fieldArray['max_lat'] = sprintf('%01.6f', $box['maxy']);
|
||||
|
||||
// handle properties
|
||||
$properties = [];
|
||||
$properties = (array)$polygon->getData();
|
||||
if (empty($properties)) {
|
||||
// seems to contain multiple polygones
|
||||
$components = $polygon->getComponents();
|
||||
// take the properties of the first polygon
|
||||
$properties = (array)$components[0]->getData();
|
||||
}
|
||||
|
||||
if (!empty($properties)) {
|
||||
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
->getQueryBuilderForTable($table);
|
||||
|
||||
$result = $queryBuilder
|
||||
->select('properties', 'properties_from_file')
|
||||
->from('tx_odsosm_vector')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq('uid', $id)
|
||||
)
|
||||
->setMaxResults(1)
|
||||
->executeQuery();
|
||||
|
||||
if ($row = $result->fetchAssociative()) {
|
||||
if ($row['properties_from_file'] && !empty($properties)) {
|
||||
|
||||
$fieldArray['properties'] = implode(', ', array_keys($properties));
|
||||
$fieldArray['properties_from_file'] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$fieldArray['min_lon'] = 0;
|
||||
$fieldArray['min_lat'] = 0;
|
||||
$fieldArray['max_lon'] = 0;
|
||||
$fieldArray['max_lat'] = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$tc = Div::getTableConfig($table);
|
||||
if ($tc['lon'] ?? false) {
|
||||
if (
|
||||
(isset($tc['address']) && ($fieldArray[$tc['address']] ?? null))
|
||||
|| (isset($tc['street']) && ($fieldArray[$tc['street']] ?? null))
|
||||
|| (isset($tc['zip']) && ($fieldArray[$tc['zip']] ?? null))
|
||||
|| (isset($tc['city']) && ($fieldArray[$tc['city']] ?? null))
|
||||
) {
|
||||
$config = Div::getConfig(['autocomplete']);
|
||||
// Search coordinates
|
||||
if ($config['autocomplete']) {
|
||||
// Generate address array with standard keys
|
||||
$address = [];
|
||||
foreach ($tc as $def => $field) {
|
||||
if ($def == strtolower($def)) {
|
||||
$address[$def] = $obj->datamap[$table][$id][$field];
|
||||
}
|
||||
}
|
||||
if ($config['autocomplete'] == 2 || (float) ($address['longitude'] ?? 0) == 0) {
|
||||
$ll = Div::updateAddress($address);
|
||||
if ($ll) {
|
||||
// Optimize address
|
||||
$address['lon'] = sprintf($tc['FORMAT'], $address['lon']);
|
||||
$address['lat'] = sprintf($tc['FORMAT'], $address['lat']);
|
||||
if (($address['type'] ?? false) == 'structured') {
|
||||
if (isset($tc['address']) && !isset($tc['street'])) {
|
||||
if ($address['street'] ?? false) {
|
||||
$address['address'] = $address['street'];
|
||||
if ($address['housenumber'] ?? false) {
|
||||
$address['address'] .= ' ' . $address['housenumber'];
|
||||
}
|
||||
}
|
||||
}
|
||||
} elseif ($tc['address'] ?? false) {
|
||||
if ($address['street'] ?? false) {
|
||||
$address['address'] = $address['street'];
|
||||
if ($address['housenumber'] ?? false) {
|
||||
$address['address'] .= ' ' . $address['housenumber'];
|
||||
}
|
||||
$address['address'] .= ', ' . $address['zip'] . ' ' . $address['city'];
|
||||
$address['address'] .= ', ' . $address['country'];
|
||||
}
|
||||
}
|
||||
|
||||
// Update fieldArray if address is set
|
||||
foreach ($tc as $def => $field) {
|
||||
if ($def != strtolower($def)) {
|
||||
continue;
|
||||
}
|
||||
if (!$address[$def]) {
|
||||
continue;
|
||||
}
|
||||
$fieldArray[$field] = $address[$def];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
374
typo3conf/ext/ods_osm/Classes/Updates/FileLocationUpdater.php
Normal file
@@ -0,0 +1,374 @@
|
||||
<?php
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2020 Alexander Bigga <alexander@bigga.de>
|
||||
* All rights reserved
|
||||
*
|
||||
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||
* free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The GNU General Public License can be found at
|
||||
* http://www.gnu.org/copyleft/gpl.html.
|
||||
*
|
||||
* This script is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
namespace Bobosch\OdsOsm\Updates;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Install\Updates\DatabaseUpdatedPrerequisite;
|
||||
use TYPO3\CMS\Install\Updates\UpgradeWizardInterface;
|
||||
use TYPO3\CMS\Install\Updates\ChattyInterface;
|
||||
|
||||
use Doctrine\DBAL\DBALException;
|
||||
use Psr\Log\LoggerAwareInterface;
|
||||
use Psr\Log\LoggerAwareTrait;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use TYPO3\CMS\Core\Core\Environment;
|
||||
use TYPO3\CMS\Core\Database\Connection;
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Database\Query\Expression\ExpressionBuilder;
|
||||
use TYPO3\CMS\Core\Resource\File;
|
||||
use TYPO3\CMS\Core\Resource\ResourceStorage;
|
||||
use TYPO3\CMS\Core\Resource\StorageRepository;
|
||||
|
||||
/**
|
||||
* Migrate location of marker and track files to new, FAL-based location
|
||||
*/
|
||||
class FileLocationUpdater implements UpgradeWizardInterface, ChattyInterface, LoggerAwareInterface
|
||||
{
|
||||
use LoggerAwareTrait;
|
||||
|
||||
/**
|
||||
* @var OutputInterface
|
||||
*/
|
||||
protected $output;
|
||||
|
||||
/**
|
||||
* @var ResourceStorage
|
||||
*/
|
||||
protected $storage;
|
||||
|
||||
/**
|
||||
* Array with table and fields to migrate
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $fieldsToMigrate = [
|
||||
'tx_odsosm_marker' => 'icon',
|
||||
'tx_odsosm_track' => 'file'
|
||||
];
|
||||
|
||||
/**
|
||||
* the source file resides here
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $sourcePath = 'uploads/tx_odsosm/';
|
||||
|
||||
/**
|
||||
* target folder after migration
|
||||
* Relative to fileadmin
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $targetPath = '_migrated/tx_odsosm/';
|
||||
|
||||
/**
|
||||
* Return the identifier for this wizard
|
||||
* This must be the same string as used in the ext_localconf class registration
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifier(): string
|
||||
{
|
||||
return 'odsOsmFileLocationUpdater';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the speaking name of this wizard
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'EXT:ods_osm: Migrate used files to FAL';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get description
|
||||
*
|
||||
* @return string Longer description of this updater
|
||||
*/
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Move marker images and track files of EXT:ods_osm to fileadmin/_migrated/tx_odsosm/ and convert reference in records.';
|
||||
}
|
||||
|
||||
/**
|
||||
* Is an update necessary?
|
||||
*
|
||||
* Is used to determine whether a wizard needs to be run.
|
||||
* Check if data for migration exists.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function updateNecessary(): bool
|
||||
{
|
||||
$numRecords = $this->falGetRecordsFromTable(true);
|
||||
if ($numRecords > 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[] All new fields and tables must exist
|
||||
*/
|
||||
public function getPrerequisites(): array
|
||||
{
|
||||
return [
|
||||
DatabaseUpdatedPrerequisite::class
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param OutputInterface $output
|
||||
*/
|
||||
public function setOutput(OutputInterface $output): void
|
||||
{
|
||||
$this->output = $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the update
|
||||
*
|
||||
* Called when a wizard reports that an update is necessary
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function executeUpdate(): bool
|
||||
{
|
||||
$result = true;
|
||||
try {
|
||||
$numRecords = $this->falGetRecordsFromTable(true);
|
||||
if ($numRecords > 0) {
|
||||
$this->falPerformUpdate();
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
// If something goes wrong, migrateField() logs an error
|
||||
$result = false;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get records from table where the field to migrate is not empty (NOT NULL and != '')
|
||||
* and also not numeric (which means that it is migrated)
|
||||
*
|
||||
* Work based on BackendLayoutIconUpdateWizard::class
|
||||
*
|
||||
* @return array|int
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function falGetRecordsFromTable($countOnly = false)
|
||||
{
|
||||
$connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
|
||||
$allResults = [];
|
||||
$numResults = 0;
|
||||
foreach(array_keys($this->fieldsToMigrate) as $table) {
|
||||
$queryBuilder = $connectionPool->getQueryBuilderForTable($table);
|
||||
$queryBuilder->getRestrictions()->removeAll();
|
||||
try {
|
||||
$result = $queryBuilder
|
||||
->select('uid', 'pid', $this->fieldsToMigrate[$table])
|
||||
->from($table)
|
||||
->where(
|
||||
$queryBuilder->expr()->isNotNull($this->fieldsToMigrate[$table]),
|
||||
$queryBuilder->expr()->neq(
|
||||
$this->fieldsToMigrate[$table],
|
||||
$queryBuilder->createNamedParameter('', Connection::PARAM_STR)
|
||||
),
|
||||
$queryBuilder->expr()->comparison(
|
||||
'CAST(CAST(' . $queryBuilder->quoteIdentifier($this->fieldsToMigrate[$table]) . ' AS DECIMAL) AS CHAR)',
|
||||
ExpressionBuilder::NEQ,
|
||||
'CAST(' . $queryBuilder->quoteIdentifier($this->fieldsToMigrate[$table]) . ' AS CHAR)'
|
||||
)
|
||||
)
|
||||
->orderBy('uid')
|
||||
->executeQuery()
|
||||
->fetchAllAssociative();
|
||||
|
||||
if ($countOnly === true) {
|
||||
$numResults += count($result);
|
||||
} else {
|
||||
$allResults[$table] = $result;
|
||||
}
|
||||
} catch (DBALException $e) {
|
||||
throw new \RuntimeException(
|
||||
'Database query failed. Error was: ' . $e->getPrevious()->getMessage(),
|
||||
1511950673
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ($countOnly === true) {
|
||||
return $numResults;
|
||||
}
|
||||
return $allResults;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Performs the database update.
|
||||
*
|
||||
* @return bool TRUE on success, FALSE on error
|
||||
*/
|
||||
protected function falPerformUpdate(): bool
|
||||
{
|
||||
$result = true;
|
||||
|
||||
try {
|
||||
$storages = GeneralUtility::makeInstance(StorageRepository::class)->findAll();
|
||||
$this->storage = $storages[0];
|
||||
|
||||
$records = $this->falGetRecordsFromTable();
|
||||
foreach ($records as $table => $recordsInTable) {
|
||||
foreach ($recordsInTable as $record) {
|
||||
$this->migrateField($table, $record);
|
||||
}
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$result = false;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates a single field.
|
||||
*
|
||||
* @param string $table
|
||||
* @param array $row
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function migrateField($table, $row)
|
||||
{
|
||||
$fieldItem = trim($row[$this->fieldsToMigrate[$table]]);
|
||||
|
||||
if (empty($fieldItem) || is_numeric($fieldItem)) {
|
||||
return;
|
||||
}
|
||||
$fileadminDirectory = rtrim($GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'], '/') . '/';
|
||||
$i = 0;
|
||||
|
||||
$storageUid = (int)$this->storage->getUid();
|
||||
$connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
|
||||
|
||||
$fileUid = null;
|
||||
$sourcePath = Environment::getPublicPath() . '/' . $this->sourcePath . $fieldItem;
|
||||
$targetDirectory = Environment::getPublicPath() . '/' . $fileadminDirectory . $this->targetPath;
|
||||
$targetPath = $targetDirectory . basename($fieldItem);
|
||||
|
||||
// maybe the file was already moved, so check if the original file still exists
|
||||
if (file_exists($sourcePath)) {
|
||||
if (!is_dir($targetDirectory)) {
|
||||
GeneralUtility::mkdir_deep($targetDirectory);
|
||||
}
|
||||
|
||||
// see if the file already exists in the storage
|
||||
$fileSha1 = sha1_file($sourcePath);
|
||||
|
||||
$queryBuilder = $connectionPool->getQueryBuilderForTable('sys_file');
|
||||
$existingFileRecord = $queryBuilder->select('uid')->from('sys_file')->where($queryBuilder->expr()->eq(
|
||||
'missing',
|
||||
$queryBuilder->createNamedParameter(0, Connection::PARAM_INT)
|
||||
), $queryBuilder->expr()->eq(
|
||||
'sha1',
|
||||
$queryBuilder->createNamedParameter($fileSha1, Connection::PARAM_STR)
|
||||
), $queryBuilder->expr()->eq(
|
||||
'storage',
|
||||
$queryBuilder->createNamedParameter($storageUid, Connection::PARAM_INT)
|
||||
))->executeQuery()->fetchAssociative();
|
||||
|
||||
// the file exists, the file does not have to be moved again
|
||||
if (is_array($existingFileRecord)) {
|
||||
$fileUid = $existingFileRecord['uid'];
|
||||
} else {
|
||||
// just move the file (no duplicate)
|
||||
rename($sourcePath, $targetPath);
|
||||
}
|
||||
}
|
||||
|
||||
if ($fileUid === null) {
|
||||
// get the File object if it hasn't been fetched before
|
||||
try {
|
||||
// if the source file does not exist, we should just continue, but leave a message in the docs;
|
||||
// ideally, the user would be informed after the update as well.
|
||||
/** @var File $file */
|
||||
$file = $this->storage->getFile($this->targetPath . $fieldItem);
|
||||
$fileUid = $file->getUid();
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
// no file found, no reference can be set
|
||||
$this->logger->notice(
|
||||
'File ' . $this->sourcePath . $fieldItem . ' does not exist. Reference was not migrated.',
|
||||
[
|
||||
'table' => $table,
|
||||
'record' => $row,
|
||||
'field' => $fieldItem,
|
||||
]
|
||||
);
|
||||
$format = 'File \'%s\' does not exist. Referencing field: %s.%d.%s. The reference was not migrated.';
|
||||
$this->output->writeln(sprintf(
|
||||
$format,
|
||||
$this->sourcePath . $fieldItem,
|
||||
$table,
|
||||
$row['uid'],
|
||||
$fieldItem
|
||||
));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ($fileUid > 0) {
|
||||
$fields = [
|
||||
'fieldname' => $this->fieldsToMigrate[$table],
|
||||
'table_local' => 'sys_file',
|
||||
'pid' => ($table === 'pages' ? $row['uid'] : $row['pid']),
|
||||
'uid_foreign' => $row['uid'],
|
||||
'uid_local' => $fileUid,
|
||||
'tablenames' => $table,
|
||||
'crdate' => time(),
|
||||
'tstamp' => time(),
|
||||
'sorting_foreign' => $i,
|
||||
];
|
||||
|
||||
$queryBuilder = $connectionPool->getQueryBuilderForTable('sys_file_reference');
|
||||
$queryBuilder->insert('sys_file_reference')->values($fields)->executeStatement();
|
||||
|
||||
++$i;
|
||||
}
|
||||
|
||||
// Update referencing table's original field to now contain the count of references,
|
||||
// but only if all new references could be set
|
||||
if ($i === 1) {
|
||||
$queryBuilder = $connectionPool->getQueryBuilderForTable($table);
|
||||
$queryBuilder->update($table)->where(
|
||||
$queryBuilder->expr()->eq(
|
||||
'uid',
|
||||
$queryBuilder->createNamedParameter($row['uid'], Connection::PARAM_INT)
|
||||
)
|
||||
)->set($this->fieldsToMigrate[$table], $i)->executeStatement();
|
||||
}
|
||||
}
|
||||
}
|
||||
235
typo3conf/ext/ods_osm/Classes/Updates/MigrateSettings.php
Normal file
@@ -0,0 +1,235 @@
|
||||
<?php
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2022 Alexander Bigga <alexander@bigga.de>
|
||||
* All rights reserved
|
||||
*
|
||||
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||
* free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The GNU General Public License can be found at
|
||||
* http://www.gnu.org/copyleft/gpl.html.
|
||||
*
|
||||
* This script is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
namespace Bobosch\OdsOsm\Updates;
|
||||
|
||||
use TYPO3\CMS\Core\Database\Connection;
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Install\Updates\DatabaseUpdatedPrerequisite;
|
||||
use TYPO3\CMS\Install\Updates\UpgradeWizardInterface;
|
||||
|
||||
/**
|
||||
* Migrate flexform settings to keep existing configuration valid.
|
||||
*/
|
||||
class MigrateSettings implements UpgradeWizardInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* Return the identifier for this wizard
|
||||
* This must be the same string as used in the ext_localconf class registration
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentifier(): string
|
||||
{
|
||||
return 'odsOsmMigrateSettings';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the speaking name of this wizard
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'EXT:ods_osm: Migrate plugin flexform settings';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the description for this wizard
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'This wizard migrates some flexform settings which has changed in ods_osm' .
|
||||
' extension. This makes the full reconfiguration of all used plugins obsolete.';
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the update
|
||||
*
|
||||
* Called when a wizard reports that an update is necessary
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function executeUpdate(): bool
|
||||
{
|
||||
// Get all tt_content data of ods_osm and update their flexforms settings
|
||||
$connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('tt_content');
|
||||
|
||||
/** @var QueryBuilder $queryBuilder */
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$statement = $queryBuilder->select('uid')
|
||||
->addSelect('pi_flexform')
|
||||
->from('tt_content')->where($queryBuilder->expr()->eq('CType', $queryBuilder->createNamedParameter('list')), $queryBuilder->expr()->like('list_type', $queryBuilder->createNamedParameter('ods_osm_%')))->executeQuery();
|
||||
|
||||
// Update the found record sets
|
||||
while ($record = $statement->fetchAssociative()) {
|
||||
// Robust error handling in case pi_flexform is NULL or empty
|
||||
if (!($record['pi_flexform'] ?? false)) {
|
||||
continue;
|
||||
}
|
||||
$oldXml = $record['pi_flexform'];
|
||||
$newXml = $this->migrateFlexformSettings($record['pi_flexform']);
|
||||
|
||||
if ($oldXml === $newXml) {
|
||||
// robust error handling:
|
||||
// if no change is necessary, this record was probably already converted and we skip the SQL UPDATE
|
||||
continue;
|
||||
}
|
||||
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$updateResult = $queryBuilder->update('tt_content')
|
||||
->where(
|
||||
$queryBuilder->expr()->eq(
|
||||
'uid',
|
||||
$queryBuilder->createNamedParameter($record['uid'], Connection::PARAM_INT)
|
||||
)
|
||||
)->set('pi_flexform', $newXml)->executeStatement();
|
||||
|
||||
// exit if at least one update statement is not successful
|
||||
if (!((bool) $updateResult)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is an update necessary?
|
||||
*
|
||||
* Looks for ods_osm plugins in tt_content table to be migrated
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function updateNecessary(): bool
|
||||
{
|
||||
$oldSettingsFound = false;
|
||||
|
||||
$connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('tt_content');
|
||||
|
||||
/** @var QueryBuilder $queryBuilder */
|
||||
$queryBuilder = $connection->createQueryBuilder();
|
||||
$statement = $queryBuilder->select('uid')
|
||||
->addSelect('pi_flexform')
|
||||
->from('tt_content')->where($queryBuilder->expr()->eq('CType', $queryBuilder->createNamedParameter('list')), $queryBuilder->expr()->like('list_type', $queryBuilder->createNamedParameter('ods_osm_%')))->executeQuery();
|
||||
|
||||
// Update the found record sets
|
||||
while ($record = $statement->fetchAssociative()) {
|
||||
if (!($record['pi_flexform'] ?? false)) {
|
||||
continue;
|
||||
}
|
||||
$oldSettingsFound = $this->checkForOldSettings($record['pi_flexform']);
|
||||
if ($oldSettingsFound) {
|
||||
// We found at least one field to be updated --> break here
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $oldSettingsFound;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of class names of Prerequisite classes
|
||||
*
|
||||
* This way a wizard can define dependencies like "database up-to-date" or
|
||||
* "reference index updated"
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function getPrerequisites(): array
|
||||
{
|
||||
return [
|
||||
DatabaseUpdatedPrerequisite::class
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $oldValue
|
||||
* @return string|bool
|
||||
*/
|
||||
protected function migrateFlexformSettings(string $oldValue): ?string
|
||||
{
|
||||
$xml = simplexml_load_string($oldValue);
|
||||
|
||||
// if something went wrong, return.
|
||||
if ($xml === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// get all field elements
|
||||
$library = $xml->xpath("//field[@index='library'][1]");
|
||||
|
||||
// get all field elements
|
||||
$fields = $xml->xpath("//field");
|
||||
|
||||
foreach ($fields as $field) {
|
||||
if ($library[0]->value != 'staticmap' && $field['index'] == $library[0]->value . '_layer') {
|
||||
// rename base layer field to base_layer
|
||||
$field['index'] = 'base_layer';
|
||||
// Copy all layers into new 'overlays' field. This is easier here, doesn't hurt the
|
||||
// frontend and will be filtered to only real 'overlays' on next saving the plugin flexform.
|
||||
$overlays = $xml->data->sheet->language->addChild('field');
|
||||
$overlays->addAttribute('index', 'overlays');
|
||||
$overlays->addChild('value', $field->value)->addAttribute('index', 'vDEF');
|
||||
} elseif ($field['index'] != $library[0]->value . '_layer' && ($field['index'] == 'layer' ||
|
||||
$field['index'] == 'openlayers_layer' ||
|
||||
$field['index'] == 'openlayers3_layer' || $field['index'] == 'leaflet_layer')) {
|
||||
// remove all other, unused layer fields from flexform xml
|
||||
unset($field[0]);
|
||||
}
|
||||
}
|
||||
|
||||
return $xml->asXML();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $flexFormXml
|
||||
* @return bool
|
||||
*/
|
||||
protected function checkForOldSettings(string $flexFormXml): bool
|
||||
{
|
||||
$xml = simplexml_load_string($flexFormXml);
|
||||
|
||||
// if something went wrong, return.
|
||||
if ($xml === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check for existing values of attribute "index"
|
||||
// * openlayers_layer
|
||||
// * leaflet_layer
|
||||
// * layer
|
||||
|
||||
$fields = $xml->xpath("//field[@index='openlayers_layer'] | //field[@index='leaflet_layer'] | //field[@index='layer']");
|
||||
|
||||
return (bool) $fields;
|
||||
}
|
||||
|
||||
}
|
||||
117
typo3conf/ext/ods_osm/Classes/Wizard/CoordinatepickerWizard.php
Normal file
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Bobosch\OdsOsm\Wizard;
|
||||
|
||||
/**
|
||||
* This file is part of the "ods_osm" Extension for TYPO3 CMS.
|
||||
* It's based on LocationMapWizard of "tt_address".
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Bobosch\OdsOsm\Div;
|
||||
use TYPO3\CMS\Backend\Form\AbstractNode;
|
||||
use TYPO3\CMS\Core\Information\Typo3Version;
|
||||
use TYPO3\CMS\Core\Localization\LanguageService;
|
||||
use TYPO3\CMS\Core\Page\JavaScriptModuleInstruction;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Core\Utility\StringUtility;
|
||||
|
||||
/**
|
||||
* Adds a wizard for location selection via map
|
||||
*/
|
||||
class CoordinatepickerWizard extends AbstractNode
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
$row = $this->data['databaseRow'];
|
||||
$paramArray = $this->data['parameterArray'];
|
||||
$resultArray = $this->initializeResultArray();
|
||||
$extConfig = Div::getConfig();
|
||||
|
||||
$nameLongitude = $paramArray['itemFormElName'];
|
||||
|
||||
if (strpos($nameLongitude, '[pi_flexform]') > 0) {
|
||||
// it's a call inside a flexform
|
||||
$lon = $row["pi_flexform"]["data"]["sDEF"]["lDEF"]["lon"]["vDEF"] != '' ? htmlspecialchars($row["pi_flexform"]["data"]["sDEF"]["lDEF"]["lon"]["vDEF"]) : '';
|
||||
$lat = $row["pi_flexform"]["data"]["sDEF"]["lDEF"]["lat"]["vDEF"] != '' ? htmlspecialchars($row["pi_flexform"]["data"]["sDEF"]["lDEF"]["lat"]["vDEF"]) : '';
|
||||
} else {
|
||||
$lat = $row['tx_odsosm_lat'] != '' ? htmlspecialchars($row['tx_odsosm_lat']) : '';
|
||||
$lon = $row['tx_odsosm_lon'] != '' ? htmlspecialchars($row['tx_odsosm_lon']) : '';
|
||||
}
|
||||
|
||||
$nameLatitude = str_replace('lon', 'lat', $nameLongitude);
|
||||
$nameLatitudeActive = str_replace('data', 'control[active]', $nameLatitude);
|
||||
$geoCodeUrl = '';
|
||||
$geoCodeUrlShort = '';
|
||||
|
||||
if (empty((float)$lat) || empty((float)$lon)) {
|
||||
// remove all after first slash in address (top, floor ...)
|
||||
$address = preg_replace('/^([^\/]*).*$/', '$1', $row['address'] ?? '') . ' ';
|
||||
$address .= $row['city'] ?? '';
|
||||
// if we have at least some address part (saves geocoding calls)
|
||||
if (trim($address)) {
|
||||
// base url
|
||||
$geoCodeUrlBase = 'https://nominatim.openstreetmap.org/search/';
|
||||
$geoCodeUrlAddress = $address;
|
||||
$geoCodeUrlCityOnly = ($row['city'] ?? '');
|
||||
// urlparams for nominatim which are fixed.
|
||||
$geoCodeUrlQuery = '?format=json&addressdetails=1&limit=1&polygon_svg=1';
|
||||
// replace newlines with spaces; remove multiple spaces
|
||||
$geoCodeUrl = trim(preg_replace('/\s\s+/', ' ', $geoCodeUrlBase . $geoCodeUrlAddress . $geoCodeUrlQuery));
|
||||
$geoCodeUrlShort = trim(preg_replace('/\s\s+/', ' ', $geoCodeUrlBase . $geoCodeUrlCityOnly . $geoCodeUrlQuery));
|
||||
}
|
||||
}
|
||||
|
||||
$resultArray['iconIdentifier'] = 'coordinate-picker-wizard';
|
||||
$resultArray['title'] = $this->getLanguageService()->sL('LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:coordinatepickerWizard');
|
||||
$resultArray['linkAttributes']['class'] = 'coordinatepickerWizard ';
|
||||
$resultArray['linkAttributes']['data-label-title'] = $this->getLanguageService()->sL('LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:coordinatepickerWizard.title');
|
||||
$resultArray['linkAttributes']['data-label-close'] = $this->getLanguageService()->sL('LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:coordinatepickerWizard.close');
|
||||
$resultArray['linkAttributes']['data-label-import'] = $this->getLanguageService()->sL('LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:coordinatepickerWizard.import');
|
||||
$resultArray['linkAttributes']['data-lat'] = $lat;
|
||||
$resultArray['linkAttributes']['data-lon'] = $lon;
|
||||
$resultArray['linkAttributes']['data-default-lat'] = $extConfig['default_lat'];
|
||||
$resultArray['linkAttributes']['data-default-lon'] = $extConfig['default_lon'];
|
||||
$resultArray['linkAttributes']['data-default-zoom'] = $extConfig['default_zoom'];
|
||||
$resultArray['linkAttributes']['data-geocodeurl'] = $geoCodeUrl;
|
||||
$resultArray['linkAttributes']['data-geocodeurlshort'] = $geoCodeUrlShort;
|
||||
$resultArray['linkAttributes']['data-namelat'] = htmlspecialchars($nameLatitude);
|
||||
$resultArray['linkAttributes']['data-namelon'] = htmlspecialchars($nameLongitude);
|
||||
$resultArray['linkAttributes']['data-namelat-active'] = htmlspecialchars($nameLatitudeActive);
|
||||
$resultArray['linkAttributes']['data-tiles'] = htmlspecialchars('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');
|
||||
$resultArray['linkAttributes']['data-copy'] = '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors';
|
||||
$resultArray['stylesheetFiles'][] = 'EXT:ods_osm/Resources/Public/JavaScript/Leaflet/Core/leaflet.css';
|
||||
$resultArray['stylesheetFiles'][] = 'EXT:ods_osm/Resources/Public/Css/Backend/leafletBackend.css';
|
||||
|
||||
$versionInformation = GeneralUtility::makeInstance(Typo3Version::class)->getMajorVersion();
|
||||
if ($versionInformation > 11) {
|
||||
$id = StringUtility::getUniqueId('t3js-formengine-fieldcontrol-');
|
||||
$resultArray['requireJsModules'][] = JavaScriptModuleInstruction::forRequireJS(
|
||||
'TYPO3/CMS/OdsOsm/Leaflet/Core/leaflet'
|
||||
)->instance($id);
|
||||
$resultArray['requireJsModules'][] = JavaScriptModuleInstruction::forRequireJS(
|
||||
'TYPO3/CMS/OdsOsm/Backend/LeafletBackend'
|
||||
)->instance($id);
|
||||
} else {
|
||||
$resultArray['requireJsModules'][] = 'TYPO3/CMS/OdsOsm/Leaflet/Core/leaflet';
|
||||
$resultArray['requireJsModules'][] = 'TYPO3/CMS/OdsOsm/Backend/LeafletBackend';
|
||||
}
|
||||
|
||||
return $resultArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return LanguageService
|
||||
*/
|
||||
protected function getLanguageService(): LanguageService
|
||||
{
|
||||
return $GLOBALS['LANG'];
|
||||
}
|
||||
}
|
||||
95
typo3conf/ext/ods_osm/Classes/Wizard/VectordrawWizard.php
Normal file
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace Bobosch\OdsOsm\Wizard;
|
||||
|
||||
/**
|
||||
* This file is part of the "ods_osm" Extension for TYPO3 CMS.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.txt file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Bobosch\OdsOsm\Div;
|
||||
use TYPO3\CMS\Backend\Form\AbstractNode;
|
||||
use TYPO3\CMS\Core\Information\Typo3Version;
|
||||
use TYPO3\CMS\Core\Localization\LanguageService;
|
||||
use TYPO3\CMS\Core\Page\JavaScriptModuleInstruction;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Core\Utility\StringUtility;
|
||||
|
||||
/**
|
||||
* Adds a wizard for drawing vectors on a map
|
||||
*/
|
||||
class VectordrawWizard extends AbstractNode
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function render(): array
|
||||
{
|
||||
$row = $this->data['databaseRow'];
|
||||
$paramArray = $this->data['parameterArray'];
|
||||
$resultArray = $this->initializeResultArray();
|
||||
$extConfig = Div::getConfig();
|
||||
|
||||
$nameDataField = $paramArray['itemFormElName'];
|
||||
|
||||
// calculate center point or use Kopenhagen as fallback
|
||||
if (!empty((float)$row['max_lon']) && !empty((float)$row['min_lon'])) {
|
||||
$lon = ($row['max_lon'] + $row['min_lon']) / 2;
|
||||
} else {
|
||||
$lon = $extConfig['default_lon'];
|
||||
}
|
||||
|
||||
if (!empty((float)$row['max_lat']) && !empty((float)$row['min_lat'])) {
|
||||
$lat = ($row['max_lat'] + $row['min_lat']) / 2;
|
||||
} else {
|
||||
$lat = $extConfig['default_lat'];
|
||||
}
|
||||
|
||||
$resultArray['iconIdentifier'] = 'vectordraw-wizard';
|
||||
$resultArray['title'] = $this->getLanguageService()->sL('LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:vectordrawWizard');
|
||||
$resultArray['linkAttributes']['class'] = 'vectordrawWizard ';
|
||||
$resultArray['linkAttributes']['data-label-title'] = $this->getLanguageService()->sL('LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:vectordrawWizard.title');
|
||||
$resultArray['linkAttributes']['data-label-close'] = $this->getLanguageService()->sL('LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:vectordrawWizard.close');
|
||||
$resultArray['linkAttributes']['data-label-import'] = $this->getLanguageService()->sL('LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:vectordrawWizard.import');
|
||||
$resultArray['linkAttributes']['data-minlat'] = empty((float)$row['min_lat']) ? null : $row['min_lat'];
|
||||
$resultArray['linkAttributes']['data-maxlat'] = empty((float)$row['max_lat']) ? null : $row['max_lat'];
|
||||
$resultArray['linkAttributes']['data-minlon'] = empty((float)$row['min_lon']) ? null : $row['min_lon'];
|
||||
$resultArray['linkAttributes']['data-maxlon'] = empty((float)$row['max_lon']) ? null : $row['max_lon'];
|
||||
$resultArray['linkAttributes']['data-lat'] = $lat;
|
||||
$resultArray['linkAttributes']['data-lon'] = $lon;
|
||||
$resultArray['linkAttributes']['data-fieldName'] = htmlspecialchars($nameDataField);
|
||||
$resultArray['linkAttributes']['data-fieldValue'] = $row['data'];
|
||||
$resultArray['linkAttributes']['data-tiles'] = htmlspecialchars('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');
|
||||
$resultArray['linkAttributes']['data-copy'] = '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors';
|
||||
$resultArray['stylesheetFiles'][] = 'EXT:ods_osm/Resources/Public/JavaScript/Leaflet/leaflet-draw/leaflet.draw.css';
|
||||
$resultArray['stylesheetFiles'][] = 'EXT:ods_osm/Resources/Public/JavaScript/Leaflet/Core/leaflet.css';
|
||||
$resultArray['stylesheetFiles'][] = 'EXT:ods_osm/Resources/Public/Css/Backend/drawvectorWizard.css';
|
||||
|
||||
$versionInformation = GeneralUtility::makeInstance(Typo3Version::class)->getMajorVersion();
|
||||
if ($versionInformation > 11) {
|
||||
$id = StringUtility::getUniqueId('t3js-formengine-fieldcontrol-');
|
||||
$resultArray['requireJsModules'][] = JavaScriptModuleInstruction::forRequireJS(
|
||||
'TYPO3/CMS/OdsOsm/Leaflet/Core/leaflet'
|
||||
)->instance($id);
|
||||
$resultArray['requireJsModules'][] = JavaScriptModuleInstruction::forRequireJS(
|
||||
'TYPO3/CMS/OdsOsm/Backend/Vectordraw'
|
||||
)->instance($id);
|
||||
} else {
|
||||
$resultArray['requireJsModules'][] = 'TYPO3/CMS/OdsOsm/Leaflet/Core/leaflet';
|
||||
$resultArray['requireJsModules'][] = 'TYPO3/CMS/OdsOsm/Backend/Vectordraw';
|
||||
}
|
||||
|
||||
return $resultArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return LanguageService
|
||||
*/
|
||||
protected function getLanguageService(): LanguageService
|
||||
{
|
||||
return $GLOBALS['LANG'];
|
||||
}
|
||||
}
|
||||
9
typo3conf/ext/ods_osm/Configuration/Backend/Routes.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
use Bobosch\OdsOsm\Wizard\Coordinatepicker;
|
||||
return [
|
||||
'coordinatepicker' => [
|
||||
'path' => '/wizard/ods_osm/coordinatepicker',
|
||||
'target' => Coordinatepicker::class . '::mainAction'
|
||||
],
|
||||
];
|
||||
441
typo3conf/ext/ods_osm/Configuration/Flexform/flexform_basic.xml
Normal file
@@ -0,0 +1,441 @@
|
||||
<T3DataStructure>
|
||||
<meta>
|
||||
<langDisable>1</langDisable>
|
||||
</meta>
|
||||
<sheets>
|
||||
<sDEF>
|
||||
<ROOT>
|
||||
<TCEforms>
|
||||
<sheetTitle>LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tt_content.pi_flexform.sheet_sDEF</sheetTitle>
|
||||
</TCEforms>
|
||||
<type>array</type>
|
||||
<el>
|
||||
<marker>
|
||||
<TCEforms>
|
||||
<label>LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tt_content.pi_flexform.marker</label>
|
||||
<description>LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tt_content.pi_flexform.marker.description</description>
|
||||
<config>
|
||||
<type>group</type>
|
||||
<internal_type>db</internal_type>
|
||||
<allowed>*</allowed>
|
||||
<size>5</size>
|
||||
<minitems>0</minitems>
|
||||
<maxitems>9999</maxitems>
|
||||
<autoSizeMax>20</autoSizeMax>
|
||||
</config>
|
||||
</TCEforms>
|
||||
</marker>
|
||||
<cluster>
|
||||
<TCEforms>
|
||||
<label>LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tt_content.pi_flexform.cluster</label>
|
||||
<config>
|
||||
<type>check</type>
|
||||
</config>
|
||||
</TCEforms>
|
||||
</cluster>
|
||||
<cluster_radius>
|
||||
<TCEforms>
|
||||
<label>LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tt_content.pi_flexform.cluster_radius</label>
|
||||
<displayCond>FIELD:cluster:!=:0</displayCond>
|
||||
<config>
|
||||
<type>input</type>
|
||||
<size>5</size>
|
||||
<eval>int</eval>
|
||||
</config>
|
||||
</TCEforms>
|
||||
</cluster_radius>
|
||||
<width>
|
||||
<TCEforms>
|
||||
<label>LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tt_content.pi_flexform.width</label>
|
||||
<config>
|
||||
<type>input</type>
|
||||
<size>5</size>
|
||||
</config>
|
||||
</TCEforms>
|
||||
</width>
|
||||
<height>
|
||||
<TCEforms>
|
||||
<label>LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tt_content.pi_flexform.height</label>
|
||||
<config>
|
||||
<type>input</type>
|
||||
<size>5</size>
|
||||
</config>
|
||||
</TCEforms>
|
||||
</height>
|
||||
<lon>
|
||||
<TCEforms>
|
||||
<label>LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_lon</label>
|
||||
<config>
|
||||
<type>input</type>
|
||||
<size>11</size>
|
||||
<eval>Bobosch\OdsOsm\Evaluation\LonLat</eval>
|
||||
<fieldControl>
|
||||
<locationMap>
|
||||
<renderType>coordinatepickerWizard</renderType>
|
||||
</locationMap>
|
||||
</fieldControl>
|
||||
</config>
|
||||
</TCEforms>
|
||||
</lon>
|
||||
<lat>
|
||||
<TCEforms>
|
||||
<label>LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_lat</label>
|
||||
<config>
|
||||
<type>input</type>
|
||||
<size>10</size>
|
||||
<eval>Bobosch\OdsOsm\Evaluation\LonLat</eval>
|
||||
</config>
|
||||
</TCEforms>
|
||||
</lat>
|
||||
<use_coords_only_nomarker>
|
||||
<TCEforms>
|
||||
<label>LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tt_content.pi_flexform.use_coords_only_nomarker</label>
|
||||
<config>
|
||||
<type>check</type>
|
||||
</config>
|
||||
</TCEforms>
|
||||
</use_coords_only_nomarker>
|
||||
<zoom>
|
||||
<TCEforms>
|
||||
<label>LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tt_content.pi_flexform.zoom</label>
|
||||
<config>
|
||||
<type>select</type>
|
||||
<renderType>selectSingle</renderType>
|
||||
<items type="array">
|
||||
<numIndex index="0" type="array">
|
||||
<numIndex index="0"></numIndex>
|
||||
<numIndex index="1"></numIndex>
|
||||
</numIndex>
|
||||
<numIndex index="1" type="array">
|
||||
<numIndex index="0">1</numIndex>
|
||||
<numIndex index="1">1</numIndex>
|
||||
</numIndex>
|
||||
<numIndex index="2" type="array">
|
||||
<numIndex index="0">2</numIndex>
|
||||
<numIndex index="1">2</numIndex>
|
||||
</numIndex>
|
||||
<numIndex index="3" type="array">
|
||||
<numIndex index="0">3</numIndex>
|
||||
<numIndex index="1">3</numIndex>
|
||||
</numIndex>
|
||||
<numIndex index="4" type="array">
|
||||
<numIndex index="0">4</numIndex>
|
||||
<numIndex index="1">4</numIndex>
|
||||
</numIndex>
|
||||
<numIndex index="5" type="array">
|
||||
<numIndex index="0">5</numIndex>
|
||||
<numIndex index="1">5</numIndex>
|
||||
</numIndex>
|
||||
<numIndex index="6" type="array">
|
||||
<numIndex index="0">6</numIndex>
|
||||
<numIndex index="1">6</numIndex>
|
||||
</numIndex>
|
||||
<numIndex index="7" type="array">
|
||||
<numIndex index="0">7</numIndex>
|
||||
<numIndex index="1">7</numIndex>
|
||||
</numIndex>
|
||||
<numIndex index="8" type="array">
|
||||
<numIndex index="0">8</numIndex>
|
||||
<numIndex index="1">8</numIndex>
|
||||
</numIndex>
|
||||
<numIndex index="9" type="array">
|
||||
<numIndex index="0">9</numIndex>
|
||||
<numIndex index="1">9</numIndex>
|
||||
</numIndex>
|
||||
<numIndex index="10" type="array">
|
||||
<numIndex index="0">10</numIndex>
|
||||
<numIndex index="1">10</numIndex>
|
||||
</numIndex>
|
||||
<numIndex index="11" type="array">
|
||||
<numIndex index="0">11</numIndex>
|
||||
<numIndex index="1">11</numIndex>
|
||||
</numIndex>
|
||||
<numIndex index="12" type="array">
|
||||
<numIndex index="0">12</numIndex>
|
||||
<numIndex index="1">12</numIndex>
|
||||
</numIndex>
|
||||
<numIndex index="13" type="array">
|
||||
<numIndex index="0">13</numIndex>
|
||||
<numIndex index="1">13</numIndex>
|
||||
</numIndex>
|
||||
<numIndex index="14" type="array">
|
||||
<numIndex index="0">14</numIndex>
|
||||
<numIndex index="1">14</numIndex>
|
||||
</numIndex>
|
||||
<numIndex index="15" type="array">
|
||||
<numIndex index="0">15</numIndex>
|
||||
<numIndex index="1">15</numIndex>
|
||||
</numIndex>
|
||||
<numIndex index="16" type="array">
|
||||
<numIndex index="0">16</numIndex>
|
||||
<numIndex index="1">16</numIndex>
|
||||
</numIndex>
|
||||
<numIndex index="17" type="array">
|
||||
<numIndex index="0">17</numIndex>
|
||||
<numIndex index="1">17</numIndex>
|
||||
</numIndex>
|
||||
<numIndex index="18" type="array">
|
||||
<numIndex index="0">18</numIndex>
|
||||
<numIndex index="1">18</numIndex>
|
||||
</numIndex>
|
||||
</items>
|
||||
</config>
|
||||
</TCEforms>
|
||||
</zoom>
|
||||
<library>
|
||||
<TCEforms>
|
||||
<label>LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tt_content.pi_flexform.library</label>
|
||||
<onChange>reload</onChange>
|
||||
<config>
|
||||
<type>select</type>
|
||||
<renderType>selectSingle</renderType>
|
||||
<items type="array">
|
||||
<numIndex index="0" type="array">
|
||||
<numIndex index="0"></numIndex>
|
||||
<numIndex index="1"></numIndex>
|
||||
</numIndex>
|
||||
<numIndex index="1" type="array">
|
||||
<numIndex index="0">Leaflet</numIndex>
|
||||
<numIndex index="1">leaflet</numIndex>
|
||||
</numIndex>
|
||||
<numIndex index="2" type="array">
|
||||
<numIndex index="0">OpenLayers</numIndex>
|
||||
<numIndex index="1">openlayers</numIndex>
|
||||
</numIndex>
|
||||
<numIndex index="4" type="array">
|
||||
<numIndex index="0">Static Map</numIndex>
|
||||
<numIndex index="1">staticmap</numIndex>
|
||||
</numIndex>
|
||||
</items>
|
||||
</config>
|
||||
</TCEforms>
|
||||
</library>
|
||||
<base_layer>
|
||||
<TCEforms>
|
||||
<label>LLL:EXT:ods_osm/Resources/Private/Language/locallang.xlf:base_layer</label>
|
||||
<description>Select used map base layer. Multiple layers may be selected here. The first layer will be used initially. All other layers are shown in the given order in the layer switcher (see below).</description>
|
||||
<displayCond>FIELD:library:IN:leaflet,openlayers</displayCond>
|
||||
<config>
|
||||
<type>select</type>
|
||||
<size>3</size>
|
||||
<renderType>selectMultipleSideBySide</renderType>
|
||||
<minitems>0</minitems>
|
||||
<maxitems>99</maxitems>
|
||||
<autoSizeMax>20</autoSizeMax>
|
||||
<foreign_table>tx_odsosm_layer</foreign_table>
|
||||
<foreign_table_where>AND tx_odsosm_layer.hidden=0 AND tx_odsosm_layer.overlay=0 AND (tx_odsosm_layer.tile_url!="") ORDER BY tx_odsosm_layer.sorting</foreign_table_where>
|
||||
</config>
|
||||
</TCEforms>
|
||||
</base_layer>
|
||||
<overlays>
|
||||
<TCEforms>
|
||||
<label>LLL:EXT:ods_osm/Resources/Private/Language/locallang.xlf:overlays</label>
|
||||
<description>LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tt_content.pi_flexform.overlays.description</description>
|
||||
<displayCond>FIELD:library:IN:leaflet,openlayers</displayCond>
|
||||
<config>
|
||||
<type>select</type>
|
||||
<size>3</size>
|
||||
<renderType>selectMultipleSideBySide</renderType>
|
||||
<minitems>0</minitems>
|
||||
<maxitems>99</maxitems>
|
||||
<autoSizeMax>20</autoSizeMax>
|
||||
<foreign_table>tx_odsosm_layer</foreign_table>
|
||||
<foreign_table_where>AND tx_odsosm_layer.hidden=0 AND tx_odsosm_layer.overlay=1 AND (tx_odsosm_layer.tile_url!="") ORDER BY tx_odsosm_layer.sorting</foreign_table_where>
|
||||
</config>
|
||||
</TCEforms>
|
||||
</overlays>
|
||||
<overlays_active>
|
||||
<TCEforms>
|
||||
<label>LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tt_content.pi_flexform.overlays_active</label>
|
||||
<description>LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tt_content.pi_flexform.overlays_active.description</description>
|
||||
<displayCond>
|
||||
<and>
|
||||
<value1>FIELD:show_layerswitcher:!=:0</value1>
|
||||
<value2>FIELD:library:IN:leaflet,openlayers</value2>
|
||||
</and>
|
||||
</displayCond>
|
||||
<config>
|
||||
<type>select</type>
|
||||
<size>3</size>
|
||||
<renderType>selectMultipleSideBySide</renderType>
|
||||
<minitems>0</minitems>
|
||||
<maxitems>99</maxitems>
|
||||
<autoSizeMax>20</autoSizeMax>
|
||||
<foreign_table>tx_odsosm_layer</foreign_table>
|
||||
<foreign_table_where>AND tx_odsosm_layer.hidden=0 AND tx_odsosm_layer.overlay=1 AND (tx_odsosm_layer.tile_url!="") ORDER BY tx_odsosm_layer.sorting</foreign_table_where>
|
||||
</config>
|
||||
</TCEforms>
|
||||
</overlays_active>
|
||||
<staticmap_layer>
|
||||
<TCEforms>
|
||||
<label>LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tt_content.pi_flexform.layer</label>
|
||||
<displayCond>FIELD:library:=:staticmap</displayCond>
|
||||
<config>
|
||||
<type>select</type>
|
||||
<renderType>selectSingle</renderType>
|
||||
<foreign_table>tx_odsosm_layer</foreign_table>
|
||||
<foreign_table_where>AND tx_odsosm_layer.hidden=0 AND tx_odsosm_layer.static_url!="" ORDER BY tx_odsosm_layer.sorting</foreign_table_where>
|
||||
<items type="array">
|
||||
<numIndex index="0" type="array">
|
||||
<numIndex index="0"></numIndex>
|
||||
<numIndex index="1"></numIndex>
|
||||
</numIndex>
|
||||
</items>
|
||||
<eval>required</eval>
|
||||
</config>
|
||||
</TCEforms>
|
||||
</staticmap_layer>
|
||||
<show_popups>
|
||||
<TCEforms>
|
||||
<label>LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tt_content.pi_flexform.show_popups</label>
|
||||
<displayCond>FIELD:library:IN:openlayers,leaflet</displayCond>
|
||||
<onChange>reload</onChange>
|
||||
<config>
|
||||
<type>select</type>
|
||||
<renderType>selectSingle</renderType>
|
||||
<items type="array">
|
||||
<numIndex index="0" type="array">
|
||||
<numIndex index="0">LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tt_content.pi_flexform.show_popups.I.0</numIndex>
|
||||
<numIndex index="1">-1</numIndex>
|
||||
</numIndex>
|
||||
<numIndex index="1" type="array">
|
||||
<numIndex index="0">LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tt_content.pi_flexform.show_popups.I.1</numIndex>
|
||||
<numIndex index="1">1</numIndex>
|
||||
</numIndex>
|
||||
<numIndex index="2" type="array">
|
||||
<numIndex index="0">LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tt_content.pi_flexform.show_popups.I.2</numIndex>
|
||||
<numIndex index="1">2</numIndex>
|
||||
</numIndex>
|
||||
</items>
|
||||
<default>1</default>
|
||||
</config>
|
||||
</TCEforms>
|
||||
</show_popups>
|
||||
<marker_popup_initial>
|
||||
<TCEforms>
|
||||
<label>LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tt_content.pi_flexform.marker_popup_intial</label>
|
||||
<displayCond>FIELD:show_popups:IN:1,3</displayCond>
|
||||
<config>
|
||||
<type>group</type>
|
||||
<internal_type>db</internal_type>
|
||||
<allowed>*</allowed>
|
||||
<size>1</size>
|
||||
<minitems>0</minitems>
|
||||
<maxitems>1</maxitems>
|
||||
</config>
|
||||
</TCEforms>
|
||||
</marker_popup_initial>
|
||||
<show_layerswitcher>
|
||||
<TCEforms>
|
||||
<label>LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tt_content.pi_flexform.show_layerswitcher</label>
|
||||
<displayCond>FIELD:library:IN:leaflet,openlayers</displayCond>
|
||||
<onChange>reload</onChange>
|
||||
<config>
|
||||
<type>select</type>
|
||||
<renderType>selectSingle</renderType>
|
||||
<items type="array">
|
||||
<numIndex index="1" type="array">
|
||||
<numIndex index="0">LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tt_content.pi_flexform.show_layerswitcher.I.0</numIndex>
|
||||
<numIndex index="1">-1</numIndex>
|
||||
</numIndex>
|
||||
<numIndex index="2" type="array">
|
||||
<numIndex index="0">LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tt_content.pi_flexform.show_layerswitcher.I.1</numIndex>
|
||||
<numIndex index="1">1</numIndex>
|
||||
</numIndex>
|
||||
<numIndex index="3" type="array">
|
||||
<numIndex index="0">LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tt_content.pi_flexform.show_layerswitcher.I.2</numIndex>
|
||||
<numIndex index="1">2</numIndex>
|
||||
</numIndex>
|
||||
</items>
|
||||
<default>1</default>
|
||||
</config>
|
||||
</TCEforms>
|
||||
</show_layerswitcher>
|
||||
<layerswitcher_activationMode>
|
||||
<TCEforms>
|
||||
<label>LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tt_content.pi_flexform.layerswitcher_activationMode</label>
|
||||
<displayCond>
|
||||
<and>
|
||||
<value1>FIELD:library:IN:openlayers</value1>
|
||||
<value2>FIELD:show_layerswitcher:!=:0</value2>
|
||||
</and>
|
||||
</displayCond>
|
||||
<config>
|
||||
<type>select</type>
|
||||
<renderType>selectSingle</renderType>
|
||||
<items type="array">
|
||||
<numIndex index="1" type="array">
|
||||
<numIndex index="0">LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tt_content.pi_flexform.show_popups.I.1</numIndex>
|
||||
<numIndex index="1">1</numIndex>
|
||||
</numIndex>
|
||||
<numIndex index="2" type="array">
|
||||
<numIndex index="0">LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tt_content.pi_flexform.show_popups.I.2</numIndex>
|
||||
<numIndex index="1">2</numIndex>
|
||||
</numIndex>
|
||||
</items>
|
||||
<default>2</default>
|
||||
</config>
|
||||
</TCEforms>
|
||||
</layerswitcher_activationMode>
|
||||
<show_fullscreen>
|
||||
<TCEforms>
|
||||
<label>LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tt_content.pi_flexform.show_fullscreen</label>
|
||||
<displayCond>FIELD:library:IN:openlayers,leaflet</displayCond>
|
||||
<config>
|
||||
<type>check</type>
|
||||
<default>1</default>
|
||||
</config>
|
||||
</TCEforms>
|
||||
</show_fullscreen>
|
||||
<show_scalebar>
|
||||
<TCEforms>
|
||||
<label>LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tt_content.pi_flexform.show_scalebar</label>
|
||||
<displayCond>FIELD:library:IN:openlayers,leaflet</displayCond>
|
||||
<config>
|
||||
<type>check</type>
|
||||
</config>
|
||||
</TCEforms>
|
||||
</show_scalebar>
|
||||
<enable_dragging>
|
||||
<TCEforms>
|
||||
<label>LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tt_content.pi_flexform.enable_dragging</label>
|
||||
<displayCond>FIELD:library:=:leaflet</displayCond>
|
||||
<config>
|
||||
<type>check</type>
|
||||
<default>1</default>
|
||||
</config>
|
||||
</TCEforms>
|
||||
</enable_dragging>
|
||||
<enable_scrollwheelzoom>
|
||||
<TCEforms>
|
||||
<label>LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tt_content.pi_flexform.enable_scrollwheelzoom</label>
|
||||
<displayCond>FIELD:library:=:leaflet</displayCond>
|
||||
<config>
|
||||
<type>check</type>
|
||||
<default>1</default>
|
||||
</config>
|
||||
</TCEforms>
|
||||
</enable_scrollwheelzoom>
|
||||
<position>
|
||||
<TCEforms>
|
||||
<label>LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tt_content.pi_flexform.position_show</label>
|
||||
<displayCond>FIELD:library:=:leaflet</displayCond>
|
||||
<config>
|
||||
<type>check</type>
|
||||
</config>
|
||||
</TCEforms>
|
||||
</position>
|
||||
<mouse_position>
|
||||
<TCEforms>
|
||||
<label>LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tt_content.pi_flexform.mouse_position</label>
|
||||
<displayCond>FIELD:library:=:openlayers</displayCond>
|
||||
<config>
|
||||
<type>check</type>
|
||||
</config>
|
||||
</TCEforms>
|
||||
</mouse_position>
|
||||
</el>
|
||||
</ROOT>
|
||||
</sDEF>
|
||||
</sheets>
|
||||
</T3DataStructure>
|
||||
21
typo3conf/ext/ods_osm/Configuration/Icons.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use TYPO3\CMS\Core\Imaging\IconProvider\BitmapIconProvider;
|
||||
|
||||
$iconPath = 'EXT:ods_osm/Resources/Public/Icons/';
|
||||
return [
|
||||
'coordinate-picker-wizard' => [
|
||||
'provider' => BitmapIconProvider::class,
|
||||
'source' => $iconPath . 'ce_wiz.png',
|
||||
],
|
||||
'vectordraw-wizard' => [
|
||||
'provider' => BitmapIconProvider::class,
|
||||
'source' => $iconPath . 'vector.png',
|
||||
],
|
||||
'ods_osm' => [
|
||||
'provider' => BitmapIconProvider::class,
|
||||
'source' => $iconPath . 'osm.png',
|
||||
],
|
||||
];
|
||||
16
typo3conf/ext/ods_osm/Configuration/Services.yaml
Normal file
@@ -0,0 +1,16 @@
|
||||
# PSR-14 EventListener for eventExtendedMultiple() in CalendarController
|
||||
services:
|
||||
_defaults:
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
public: false
|
||||
|
||||
Bobosch\OdsOsm\:
|
||||
resource: '../Classes/*'
|
||||
|
||||
Bobosch\OdsOsm\EventListener\CalendarizeOdsOsmSqlListener:
|
||||
tags:
|
||||
- name: event.listener
|
||||
identifier: 'calendarizeOdsOsmSql'
|
||||
event: TYPO3\CMS\Core\Database\Event\AlterTableDefinitionStatementsEvent
|
||||
after: 'calendarizeField'
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
defined('TYPO3') || die();
|
||||
|
||||
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
|
||||
|
||||
/* --------------------------------------------------
|
||||
Extend existing tables
|
||||
-------------------------------------------------- */
|
||||
|
||||
$tempColumns = [
|
||||
'tx_odsosm_marker' => [
|
||||
'exclude' => 1,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tt_address_group.tx_odsosm_marker',
|
||||
'config' => [
|
||||
'type' => 'group',
|
||||
'allowed' => 'tx_odsosm_marker',
|
||||
'size' => 1,
|
||||
'minitems' => 0,
|
||||
'maxitems' => 1,
|
||||
'default' => 0,
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
ExtensionManagementUtility::addTCAcolumns('fe_groups', $tempColumns);
|
||||
ExtensionManagementUtility::addToAllTCAtypes('fe_groups', 'tx_odsosm_marker');
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
defined('TYPO3') || die();
|
||||
|
||||
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
|
||||
use Bobosch\OdsOsm\Evaluation\LonLat;
|
||||
|
||||
$tempColumns = [
|
||||
'tx_odsosm_lon' => [ // DECIMAL(9,6)
|
||||
'exclude' => 1,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_lon',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => 11,
|
||||
'max' => 11,
|
||||
'checkbox' => '0.000000',
|
||||
'eval' => LonLat::class,
|
||||
'fieldControl' => [
|
||||
'locationMap' => [
|
||||
'renderType' => 'coordinatepickerWizard'
|
||||
]
|
||||
],
|
||||
'default' => 0.000000,
|
||||
]
|
||||
],
|
||||
'tx_odsosm_lat' => [ // DECIMAL(8,6)
|
||||
'exclude' => 1,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_lat',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => 10,
|
||||
'max' => 10,
|
||||
'eval' => LonLat::class,
|
||||
'default' => 0.000000,
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
ExtensionManagementUtility::addTCAcolumns('fe_users', $tempColumns);
|
||||
ExtensionManagementUtility::addToAllTCAtypes('fe_users', 'tx_odsosm_lon', '', 'after:country');
|
||||
ExtensionManagementUtility::addFieldsToAllPalettesOfField('fe_users', 'tx_odsosm_lon', 'tx_odsosm_lat');
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
defined('TYPO3') || die();
|
||||
|
||||
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
|
||||
|
||||
/* --------------------------------------------------
|
||||
Extend existing tables
|
||||
-------------------------------------------------- */
|
||||
|
||||
$tempColumns = [
|
||||
'tx_odsosm_marker' => [
|
||||
'exclude' => 1,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tt_address_group.tx_odsosm_marker',
|
||||
'config' => [
|
||||
'type' => 'group',
|
||||
'allowed' => 'tx_odsosm_marker',
|
||||
'size' => 1,
|
||||
'minitems' => 0,
|
||||
'maxitems' => 1,
|
||||
'default' => 0,
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
ExtensionManagementUtility::addTCAcolumns('sys_category', $tempColumns);
|
||||
ExtensionManagementUtility::addToAllTCAtypes('sys_category', 'tx_odsosm_marker');
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
defined('TYPO3') || die();
|
||||
|
||||
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
|
||||
|
||||
ExtensionManagementUtility::addStaticFile(
|
||||
'ods_osm',
|
||||
'Configuration/TypoScript/',
|
||||
'Template OpenStreetMap'
|
||||
);
|
||||
|
||||
ExtensionManagementUtility::addStaticFile(
|
||||
'ods_osm',
|
||||
'Configuration/TypoScript/Calendarize/',
|
||||
'Template OpenStreetMap for Calendarize'
|
||||
);
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
defined('TYPO3') || die();
|
||||
|
||||
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
|
||||
|
||||
/* --------------------------------------------------
|
||||
Plugin
|
||||
-------------------------------------------------- */
|
||||
|
||||
ExtensionManagementUtility::addPlugin(
|
||||
[
|
||||
'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tt_content.list_type_pi1',
|
||||
'ods_osm_pi1'
|
||||
],
|
||||
'list_type',
|
||||
'ods_osm'
|
||||
);
|
||||
|
||||
ExtensionManagementUtility::addPiFlexFormValue(
|
||||
'ods_osm_pi1',
|
||||
'FILE:EXT:ods_osm/Configuration/Flexform/flexform_basic.xml'
|
||||
);
|
||||
|
||||
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist']['ods_osm_pi1'] = 'pi_flexform';
|
||||
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_excludelist']['ods_osm_pi1'] = 'layout,select_key,pages,recursive';
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
defined('TYPO3') || die();
|
||||
|
||||
use Bobosch\OdsOsm\Evaluation\LonLat;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
|
||||
|
||||
if (ExtensionManagementUtility::isLoaded('calendarize')) {
|
||||
$tempColumns = [
|
||||
'tx_odsosm_lon' => [ // DECIMAL(9,6)
|
||||
'exclude' => 1,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_lon',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => 11,
|
||||
'max' => 11,
|
||||
'checkbox' => '0.000000',
|
||||
'eval' => LonLat::class,
|
||||
'fieldControl' => [
|
||||
'locationMap' => [
|
||||
'renderType' => 'coordinatepickerWizard'
|
||||
]
|
||||
],
|
||||
'default' => 0.000000,
|
||||
]
|
||||
],
|
||||
'tx_odsosm_lat' => [ // DECIMAL(8,6)
|
||||
'exclude' => 1,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_lat',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => 10,
|
||||
'max' => 10,
|
||||
'eval' => LonLat::class,
|
||||
'default' => 0.000000,
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
ExtensionManagementUtility::addTCAcolumns('tx_calendarize_domain_model_event', $tempColumns);
|
||||
ExtensionManagementUtility::addToAllTCAtypes('tx_calendarize_domain_model_event', 'tx_odsosm_lon', '', 'after:location');
|
||||
ExtensionManagementUtility::addFieldsToAllPalettesOfField('tx_calendarize_domain_model_event', 'tx_odsosm_lon', 'tx_odsosm_lat');
|
||||
}
|
||||
131
typo3conf/ext/ods_osm/Configuration/TCA/tx_odsosm_geocache.php
Normal file
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
|
||||
use Bobosch\OdsOsm\Evaluation\LonLat;
|
||||
return [
|
||||
'ctrl' => [
|
||||
'title' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_geocache',
|
||||
'label' => 'zip',
|
||||
'tstamp' => 'tstamp',
|
||||
'crdate' => 'crdate',
|
||||
'default_sortby' => 'ORDER BY zip',
|
||||
'delete' => 'deleted',
|
||||
'rootLevel' => 1,
|
||||
'iconfile' => 'EXT:ods_osm/Resources/Public/Icons/icon_tx_odsosm_geocache.png',
|
||||
],
|
||||
'columns' => [
|
||||
'cache_hit' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_geocache.cache_hit',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => 10,
|
||||
'max' => 10,
|
||||
'eval' => '',
|
||||
]
|
||||
],
|
||||
'service_hit' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_geocache.service_hit',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => 10,
|
||||
'max' => 10,
|
||||
'eval' => '',
|
||||
]
|
||||
],
|
||||
'search_city' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_geocache.city',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => 30,
|
||||
'max' => 255,
|
||||
]
|
||||
],
|
||||
'country' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_geocache.country',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => 2,
|
||||
'max' => 2,
|
||||
]
|
||||
],
|
||||
'state' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_geocache.state',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => 30,
|
||||
'max' => 255,
|
||||
]
|
||||
],
|
||||
'city' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_geocache.city',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => 30,
|
||||
'max' => 255,
|
||||
]
|
||||
],
|
||||
'zip' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_geocache.zip',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => 5,
|
||||
'max' => 5,
|
||||
]
|
||||
],
|
||||
'street' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_geocache.street',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => 30,
|
||||
'max' => 255,
|
||||
]
|
||||
],
|
||||
'housenumber' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_geocache.housenumber',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => 5,
|
||||
'max' => 5,
|
||||
]
|
||||
],
|
||||
'lon' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_geocache.lon',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => 11,
|
||||
'max' => 11,
|
||||
'eval' => LonLat::class,
|
||||
]
|
||||
],
|
||||
'lat' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_geocache.lat',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => 11,
|
||||
'max' => 10,
|
||||
'eval' => LonLat::class,
|
||||
]
|
||||
],
|
||||
],
|
||||
'types' => [
|
||||
'0' => [
|
||||
'showitem' => 'cache_hit,service_hit,search_city,country,state,city,zip,street,housenumber,lon,
|
||||
--palette--;;latinfo'
|
||||
]
|
||||
],
|
||||
'palettes' => [
|
||||
'latinfo' => [
|
||||
'showitem' => 'lat'
|
||||
]
|
||||
]
|
||||
];
|
||||
138
typo3conf/ext/ods_osm/Configuration/TCA/tx_odsosm_layer.php
Normal file
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
return [
|
||||
'ctrl' => [
|
||||
'title' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_layer',
|
||||
'label' => 'title',
|
||||
'tstamp' => 'tstamp',
|
||||
'crdate' => 'crdate',
|
||||
'sortby' => 'sorting',
|
||||
'delete' => 'deleted',
|
||||
'rootLevel' => 1,
|
||||
'enablecolumns' => [
|
||||
'disabled' => 'hidden',
|
||||
],
|
||||
'iconfile' => 'EXT:ods_osm/Resources/Public/Icons/icon_tx_odsosm_layer.png',
|
||||
],
|
||||
'columns' => [
|
||||
'hidden' => [
|
||||
'exclude' => true,
|
||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.enabled',
|
||||
'config' => [
|
||||
'type' => 'check',
|
||||
'renderType' => 'checkboxToggle',
|
||||
'default' => 0,
|
||||
'items' => [
|
||||
[
|
||||
0 => '',
|
||||
'invertStateDisplay' => true
|
||||
]
|
||||
],
|
||||
]
|
||||
],
|
||||
'title' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_layer.title',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => '30',
|
||||
]
|
||||
],
|
||||
'overlay' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_layer.overlay',
|
||||
'config' => [
|
||||
'type' => 'check',
|
||||
'default' => '0'
|
||||
]
|
||||
],
|
||||
'javascript_include' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_layer.javascript_include',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => '30',
|
||||
'checkbox' => '',
|
||||
]
|
||||
],
|
||||
'javascript_openlayers' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_layer.javascript_openlayers',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => '30',
|
||||
]
|
||||
],
|
||||
'static_url' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_layer.static_url',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => '30',
|
||||
]
|
||||
],
|
||||
'tile_url' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_layer.tile_url',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => '30',
|
||||
]
|
||||
],
|
||||
'tile_https' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_layer.tile_https',
|
||||
'config' => [
|
||||
'type' => 'check',
|
||||
'default' => '0',
|
||||
]
|
||||
],
|
||||
'min_zoom' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_layer.min_zoom',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => '2',
|
||||
'eval' => 'num',
|
||||
]
|
||||
],
|
||||
'max_zoom' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_layer.max_zoom',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => '2',
|
||||
'eval' => 'num',
|
||||
]
|
||||
],
|
||||
'subdomains' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_layer.subdomains',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => '5',
|
||||
]
|
||||
],
|
||||
'attribution' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_layer.attribution',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => '30',
|
||||
]
|
||||
],
|
||||
'homepage' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_layer.homepage',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => '30',
|
||||
]
|
||||
],
|
||||
],
|
||||
'types' => [
|
||||
'0' => ['showitem' => 'hidden, title, overlay, javascript_include, javascript_openlayers, static_url, tile_url, tile_https, min_zoom, max_zoom, subdomains, attribution, homepage']
|
||||
],
|
||||
'palettes' => [
|
||||
'1' => ['showitem' => '']
|
||||
]
|
||||
];
|
||||
118
typo3conf/ext/ods_osm/Configuration/TCA/tx_odsosm_marker.php
Normal file
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
|
||||
return [
|
||||
'ctrl' => [
|
||||
'title' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_marker',
|
||||
'label' => 'title',
|
||||
'tstamp' => 'tstamp',
|
||||
'crdate' => 'crdate',
|
||||
'default_sortby' => 'ORDER BY title',
|
||||
'delete' => 'deleted',
|
||||
'iconfile' => 'EXT:ods_osm/Resources/Public/Icons/icon_tx_odsosm_marker.png',
|
||||
],
|
||||
'columns' => [
|
||||
'title' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_marker.title',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => '30',
|
||||
]
|
||||
],
|
||||
'icon' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_marker.icon',
|
||||
'config' => ExtensionManagementUtility::getFileFieldTCAConfig(
|
||||
'icon',
|
||||
[
|
||||
'maxitems' => 1,
|
||||
'appearance' => [
|
||||
'createNewRelationLinkTitle' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:images.addFileReference'
|
||||
],
|
||||
'foreign_match_fields' => [
|
||||
'fieldname' => 'icon',
|
||||
'tablenames' => 'tx_odsosm_marker',
|
||||
],
|
||||
'default' => 0,
|
||||
],
|
||||
$GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext']
|
||||
)
|
||||
],
|
||||
'size_x' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_marker.size_x',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => 4,
|
||||
'max' => 4,
|
||||
'eval' => 'int',
|
||||
'checkbox' => 0,
|
||||
'range' => [
|
||||
'lower' => 0,
|
||||
'upper' => 9999,
|
||||
],
|
||||
'default' => 0
|
||||
]
|
||||
],
|
||||
'size_y' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_marker.size_y',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => 4,
|
||||
'max' => 4,
|
||||
'eval' => 'int',
|
||||
'checkbox' => 0,
|
||||
'range' => [
|
||||
'lower' => 0,
|
||||
'upper' => 9999,
|
||||
],
|
||||
'default' => 0
|
||||
]
|
||||
],
|
||||
'offset_x' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_marker.offset_x',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => 5,
|
||||
'max' => 5,
|
||||
'eval' => 'int',
|
||||
'checkbox' => 0,
|
||||
'range' => [
|
||||
'lower' => -9999,
|
||||
'upper' => 9999,
|
||||
],
|
||||
'default' => 0
|
||||
]
|
||||
],
|
||||
'offset_y' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_marker.offset_y',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => 5,
|
||||
'max' => 5,
|
||||
'eval' => 'int',
|
||||
'checkbox' => 0,
|
||||
'range' => [
|
||||
'lower' => -9999,
|
||||
'upper' => 9999,
|
||||
],
|
||||
'default' => 0
|
||||
]
|
||||
],
|
||||
],
|
||||
'types' => [
|
||||
'0' => [
|
||||
'showitem' => 'title, icon,
|
||||
--palette--;;sizeinfo'
|
||||
]
|
||||
],
|
||||
'palettes' => [
|
||||
'sizeinfo' => [
|
||||
'showitem' => 'size_x, size_y, offset_x, offset_y'
|
||||
]
|
||||
]
|
||||
];
|
||||
131
typo3conf/ext/ods_osm/Configuration/TCA/tx_odsosm_track.php
Normal file
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
|
||||
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
|
||||
return [
|
||||
'ctrl' => [
|
||||
'title' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_track',
|
||||
'label' => 'title',
|
||||
'tstamp' => 'tstamp',
|
||||
'crdate' => 'crdate',
|
||||
'default_sortby' => 'ORDER BY title',
|
||||
'delete' => 'deleted',
|
||||
'enablecolumns' => [
|
||||
'disabled' => 'hidden',
|
||||
],
|
||||
'iconfile' => 'EXT:ods_osm/Resources/Public/Icons/icon_tx_odsosm_track.png',
|
||||
],
|
||||
'columns' => [
|
||||
'hidden' => [
|
||||
'exclude' => true,
|
||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.enabled',
|
||||
'config' => [
|
||||
'type' => 'check',
|
||||
'renderType' => 'checkboxToggle',
|
||||
'default' => 0,
|
||||
'items' => [
|
||||
[
|
||||
0 => '',
|
||||
'invertStateDisplay' => true
|
||||
]
|
||||
],
|
||||
]
|
||||
],
|
||||
'title' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_track.title',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => 30,
|
||||
]
|
||||
],
|
||||
'color' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_track.color',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => 10,
|
||||
'max' => 10,
|
||||
'default' => '#37b7ff',
|
||||
'eval' => 'nospace,trim',
|
||||
'renderType' => 'colorpicker',
|
||||
]
|
||||
],
|
||||
'width' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_track.width',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => 3,
|
||||
'max' => 3,
|
||||
'default' => 5,
|
||||
'range' => [
|
||||
'lower' => 1,
|
||||
'upper' => 255
|
||||
],
|
||||
'eval' => 'int',
|
||||
]
|
||||
],
|
||||
'file' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_track.file',
|
||||
'config' => ExtensionManagementUtility::getFileFieldTCAConfig(
|
||||
'file',
|
||||
[
|
||||
'maxitems' => 1,
|
||||
'appearance' => [
|
||||
'createNewRelationLinkTitle' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db:tx_odsosm_track.file.add'
|
||||
],
|
||||
'foreign_match_fields' => [
|
||||
'fieldname' => 'file',
|
||||
'tablenames' => 'tx_odsosm_track',
|
||||
],
|
||||
'default' => 0,
|
||||
],
|
||||
'gpx,kml'
|
||||
)
|
||||
],
|
||||
'min_lon' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_track.min_lon',
|
||||
'config' => [
|
||||
'type' => 'none',
|
||||
'size' => 8,
|
||||
]
|
||||
],
|
||||
'min_lat' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_track.min_lat',
|
||||
'config' => [
|
||||
'type' => 'none',
|
||||
'size' => 8,
|
||||
]
|
||||
],
|
||||
'max_lon' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_track.max_lon',
|
||||
'config' => [
|
||||
'type' => 'none',
|
||||
'size' => 8,
|
||||
]
|
||||
],
|
||||
'max_lat' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_track.max_lat',
|
||||
'config' => [
|
||||
'type' => 'none',
|
||||
'size' => 8,
|
||||
]
|
||||
],
|
||||
],
|
||||
'types' => [
|
||||
'0' => [
|
||||
'showitem' => 'hidden, title, color, width, file,
|
||||
--palette--;;lonlatinfo'
|
||||
]
|
||||
],
|
||||
'palettes' => [
|
||||
'lonlatinfo' => [
|
||||
'showitem' => 'min_lon, min_lat, max_lon, max_lat'
|
||||
]
|
||||
]
|
||||
];
|
||||
165
typo3conf/ext/ods_osm/Configuration/TCA/tx_odsosm_vector.php
Normal file
@@ -0,0 +1,165 @@
|
||||
<?php
|
||||
|
||||
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
|
||||
return [
|
||||
'ctrl' => [
|
||||
'title' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_vector',
|
||||
'label' => 'title',
|
||||
'tstamp' => 'tstamp',
|
||||
'crdate' => 'crdate',
|
||||
'default_sortby' => 'ORDER BY title',
|
||||
'delete' => 'deleted',
|
||||
'enablecolumns' => [
|
||||
'disabled' => 'hidden',
|
||||
],
|
||||
'iconfile' => 'EXT:ods_osm/Resources/Public/Icons/icon_tx_odsosm_vector.png',
|
||||
],
|
||||
'columns' => [
|
||||
'hidden' => [
|
||||
'exclude' => true,
|
||||
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.enabled',
|
||||
'config' => [
|
||||
'type' => 'check',
|
||||
'renderType' => 'checkboxToggle',
|
||||
'default' => 0,
|
||||
'items' => [
|
||||
[
|
||||
0 => '',
|
||||
'invertStateDisplay' => true
|
||||
]
|
||||
],
|
||||
]
|
||||
],
|
||||
'title' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_vector.title',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => 30,
|
||||
]
|
||||
],
|
||||
'data' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_vector.data',
|
||||
'config' => [
|
||||
'type' => 'text',
|
||||
'rows' => 10,
|
||||
'cols' => 60,
|
||||
'max' => 20000,
|
||||
'fieldControl' => [
|
||||
'vectordrawWizard' => [
|
||||
'renderType' => 'vectordrawWizard'
|
||||
]
|
||||
]
|
||||
]
|
||||
],
|
||||
'color' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_track.color',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => 10,
|
||||
'max' => 10,
|
||||
'default' => '#3388ff',
|
||||
'eval' => 'nospace,trim',
|
||||
'renderType' => 'colorpicker',
|
||||
]
|
||||
],
|
||||
'width' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_track.width',
|
||||
'config' => [
|
||||
'type' => 'input',
|
||||
'size' => 3,
|
||||
'max' => 3,
|
||||
'default' => 3,
|
||||
'range' => [
|
||||
'lower' => 0,
|
||||
'upper' => 255
|
||||
],
|
||||
'eval' => 'int',
|
||||
]
|
||||
],
|
||||
'file' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_vector.file',
|
||||
'config' => ExtensionManagementUtility::getFileFieldTCAConfig(
|
||||
'file',
|
||||
[
|
||||
'maxitems' => 1,
|
||||
'appearance' => [
|
||||
'createNewRelationLinkTitle' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db:tx_odsosm_vector.file.add'
|
||||
],
|
||||
'foreign_match_fields' => [
|
||||
'fieldname' => 'file',
|
||||
'tablenames' => 'tx_odsosm_vector',
|
||||
],
|
||||
'default' => 0,
|
||||
],
|
||||
'geojson,json'
|
||||
)
|
||||
],
|
||||
'properties' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_vector.properties',
|
||||
'config' => [
|
||||
'type' => 'text',
|
||||
'rows' => 5,
|
||||
'cols' => 60,
|
||||
'max' => 2000,
|
||||
]
|
||||
],
|
||||
'properties_from_file' => [
|
||||
'exclude' => true,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_vector.properties_from_file',
|
||||
'config' => [
|
||||
'type' => 'check',
|
||||
'renderType' => 'checkboxToggle',
|
||||
'default' => 1,
|
||||
]
|
||||
],
|
||||
'min_lon' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_track.min_lon',
|
||||
'config' => [
|
||||
'type' => 'none',
|
||||
'size' => 8,
|
||||
]
|
||||
],
|
||||
'min_lat' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_track.min_lat',
|
||||
'config' => [
|
||||
'type' => 'none',
|
||||
'size' => 8,
|
||||
]
|
||||
],
|
||||
'max_lon' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_track.max_lon',
|
||||
'config' => [
|
||||
'type' => 'none',
|
||||
'size' => 8,
|
||||
]
|
||||
],
|
||||
'max_lat' => [
|
||||
'exclude' => 0,
|
||||
'label' => 'LLL:EXT:ods_osm/Resources/Private/Language/locallang_db.xlf:tx_odsosm_track.max_lat',
|
||||
'config' => [
|
||||
'type' => 'none',
|
||||
'size' => 8,
|
||||
]
|
||||
],
|
||||
],
|
||||
'types' => [
|
||||
'0' => [
|
||||
'showitem' => 'hidden, title, data, color, width, file, properties, properties_from_file,
|
||||
--palette--;;lonlatinfo'
|
||||
]
|
||||
],
|
||||
'palettes' => [
|
||||
'lonlatinfo' => [
|
||||
'showitem' => 'min_lon, min_lat, max_lon, max_lat'
|
||||
]
|
||||
]
|
||||
];
|
||||
@@ -0,0 +1,24 @@
|
||||
plugin.tx_calendarize.view.templateRootPaths.200 = EXT:ods_osm/Resources/Private/Extensions/Calendarize/Templates/
|
||||
|
||||
plugin.tx_odsosm_pi1 {
|
||||
|
||||
marker.tx_calendarize_domain_model_event.data = GP:tx_calendarize_calendar|index
|
||||
|
||||
use_coords_only_nomarker = 1
|
||||
|
||||
width = 480px
|
||||
height = 360px
|
||||
|
||||
zoom = 14
|
||||
|
||||
layer = 1
|
||||
|
||||
show_popups = 1
|
||||
marker_popup_initial = 1
|
||||
|
||||
show_fullscreen = 1
|
||||
|
||||
show_scalebar = 1
|
||||
|
||||
library = leaflet
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
plugin.tx_odsosm_pi1 {
|
||||
# cat=OpenStreetMap//0010; type=options[none,jquery]; label=JavaScript library
|
||||
JSlibrary = none
|
||||
|
||||
# cat=OpenStreetMap//0021; type=options[Leaflet=leaflet,Openlayers=openlayers,Static=staticmap]; label=Library: Choose between https://leafletjs.com/, http://openlayers.org/ or a static map without javascript.
|
||||
library = leaflet
|
||||
|
||||
# cat=OpenStreetMap//0030; type=boolean; label=External control: Allow control with GET or POST.
|
||||
external_control = 0
|
||||
|
||||
# cat=OpenStreetMap//1000; type=string; label=Width: Width of the map.
|
||||
width = 80vw
|
||||
|
||||
# cat=OpenStreetMap//1010; type=string; label=Height: Height of the map.
|
||||
height = 80vh
|
||||
|
||||
# cat=OpenStreetMap//1020; type=options[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18]; label=Zoom: Zoom level.
|
||||
zoom = 15
|
||||
|
||||
# cat=OpenStreetMap//1030; type=string; label=Base layer IDs: Show maps with the given IDs. The user can switch between these base layers if the layerswitcher is enabled.
|
||||
layer = 1
|
||||
|
||||
# cat=OpenStreetMap//1040; type=boolean; label=Cluster: Cluster marker at lower map zoom.
|
||||
cluster = 0
|
||||
|
||||
# cat=OpenStreetMap//1041; type=int; label=Cluster radius: Cluster marker in given radius.
|
||||
cluster_radius = 80
|
||||
|
||||
# cat=OpenStreetMap//1050; type=options[Hide map=0,Show map=1]; label=No marker: What to do if no marker is defined.
|
||||
no_marker = 1
|
||||
|
||||
# cat=OpenStreetMap//1060; type=boolean; label=Use coordinates only if no marker exists: Use the default coordinates only if no marker exists.
|
||||
use_coords_only_nomarker = 1
|
||||
|
||||
# cat=OpenStreetMap//1060; type=boolean; label=Position: Get current user postion from browser to center the map.
|
||||
position = 0
|
||||
|
||||
# cat=OpenStreetMap//2000; type=boolean; label=Show mouse position.
|
||||
mouse_position = 0
|
||||
|
||||
# cat=OpenStreetMap//2020; type=options[No=0,Click=1,Hover=2]; label=Show popup: Show popup window with record information.
|
||||
show_popups = 1
|
||||
|
||||
# cat=OpenStreetMap//2030; type=options[No=0,Closed=1,Opened=2]; label=Show layerswitcher: Show layerswitcher which allows the user to hide markers from the same group.
|
||||
show_layerswitcher = 1
|
||||
|
||||
# cat=OpenStreetMap//2030; type=boolean; label=Show Fullscreen: Show Fullscreen Button.
|
||||
show_fullscreen = 1
|
||||
|
||||
# cat=OpenStreetMap//2050; type=boolean; label=Show ScaleBar: Show a scale line on the map.
|
||||
show_scalebar = 0
|
||||
}
|
||||
151
typo3conf/ext/ods_osm/Configuration/TypoScript/setup.typoscript
Normal file
@@ -0,0 +1,151 @@
|
||||
plugin.tx_odsosm_pi1 {
|
||||
userFunc = Bobosch\OdsOsm\Controller\PluginController->main
|
||||
|
||||
# Script configuration
|
||||
|
||||
JSlibrary = {$plugin.tx_odsosm_pi1.JSlibrary}
|
||||
library = {$plugin.tx_odsosm_pi1.library}
|
||||
external_control = {$plugin.tx_odsosm_pi1.external_control}
|
||||
|
||||
# Marker
|
||||
|
||||
marker {
|
||||
pages =
|
||||
fe_users =
|
||||
fe_groups =
|
||||
tx_odsosm_track =
|
||||
tx_odsosm_marker =
|
||||
tt_address =
|
||||
sys_category =
|
||||
tx_calendarize_domain_model_event =
|
||||
}
|
||||
|
||||
# see documentation for examples
|
||||
icon {
|
||||
fe_users = IMAGE
|
||||
tt_address = IMAGE
|
||||
}
|
||||
|
||||
popup {
|
||||
tx_odsosm_vector = COA
|
||||
tx_odsosm_vector {
|
||||
10 = TEXT
|
||||
10 {
|
||||
field = title
|
||||
wrap = <h2>|</h2>
|
||||
}
|
||||
}
|
||||
fe_users = COA
|
||||
fe_users {
|
||||
9 = FILES
|
||||
9 {
|
||||
references {
|
||||
table = fe_users
|
||||
fieldName = image
|
||||
}
|
||||
renderObj = IMAGE
|
||||
renderObj {
|
||||
file {
|
||||
import.data = file:current:uid
|
||||
treatIdAsReference = 1
|
||||
width = 150c
|
||||
height = 150c
|
||||
}
|
||||
altText.data = file:current:alternative
|
||||
titleText.data = file:current:title
|
||||
stdWrap.typolink.parameter.data = file:current:link
|
||||
}
|
||||
}
|
||||
10 = TEXT
|
||||
10 {
|
||||
field = name
|
||||
wrap = <h2>|</h2>
|
||||
override = {field:first_name} {field:middle_name} {field:last_name}
|
||||
override.insertData = 1
|
||||
override.if.isFalse.field = name
|
||||
}
|
||||
20 = TEXT
|
||||
20 {
|
||||
field = description
|
||||
htmlSpecialChars = 1
|
||||
}
|
||||
}
|
||||
tt_address = COA
|
||||
tt_address {
|
||||
9 = FILES
|
||||
9 {
|
||||
references {
|
||||
table = tt_address
|
||||
fieldName = image
|
||||
}
|
||||
renderObj = IMAGE
|
||||
renderObj {
|
||||
file {
|
||||
import.data = file:current:uid
|
||||
treatIdAsReference = 1
|
||||
width = 150c
|
||||
height = 150c
|
||||
}
|
||||
altText.data = file:current:alternative
|
||||
titleText.data = file:current:title
|
||||
stdWrap.typolink.parameter.data = file:current:link
|
||||
}
|
||||
}
|
||||
10 = TEXT
|
||||
10 {
|
||||
field = name
|
||||
wrap = <h2>|</h2>
|
||||
}
|
||||
20 = TEXT
|
||||
20 {
|
||||
field = description
|
||||
htmlSpecialChars = 0
|
||||
}
|
||||
}
|
||||
tx_calendarize_domain_model_event = COA
|
||||
tx_calendarize_domain_model_event {
|
||||
10 = TEXT
|
||||
10 {
|
||||
field = location
|
||||
wrap = <h2>|</h2>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Map configuration
|
||||
|
||||
width = {$plugin.tx_odsosm_pi1.width}
|
||||
height = {$plugin.tx_odsosm_pi1.height}
|
||||
zoom = {$plugin.tx_odsosm_pi1.zoom}
|
||||
layer = {$plugin.tx_odsosm_pi1.layer}
|
||||
cluster = {$plugin.tx_odsosm_pi1.cluster}
|
||||
cluster_radius = {$plugin.tx_odsosm_pi1.cluster_radius}
|
||||
no_marker = {$plugin.tx_odsosm_pi1.no_marker}
|
||||
use_coords_only_nomarker = {$plugin.tx_odsosm_pi1.use_coords_only_nomarker}
|
||||
position = {$plugin.tx_odsosm_pi1.position}
|
||||
|
||||
# User controls
|
||||
|
||||
mouse_position = {$plugin.tx_odsosm_pi1.mouse_position}
|
||||
show_popups = {$plugin.tx_odsosm_pi1.show_popups}
|
||||
marker_popup_initial =
|
||||
show_layerswitcher = {$plugin.tx_odsosm_pi1.show_layerswitcher}
|
||||
show_scalebar = {$plugin.tx_odsosm_pi1.show_scalebar}
|
||||
|
||||
show_fullscreen = {$plugin.tx_odsosm_pi1.show_fullscreen}
|
||||
|
||||
# Leaflet only
|
||||
enable_scrollwheelzoom = 1
|
||||
enable_dragging = 1
|
||||
position = 0
|
||||
|
||||
# OpenLayers only
|
||||
layerswitcher_activationMode = 1
|
||||
mouse_position = 0
|
||||
}
|
||||
|
||||
page {
|
||||
includeCSS {
|
||||
ods-osm = EXT:ods_osm/Resources/Public/Css/ods_osm.css
|
||||
}
|
||||
}
|
||||
308
typo3conf/ext/ods_osm/Documentation/Administrators/Index.rst
Normal file
@@ -0,0 +1,308 @@
|
||||
==============
|
||||
Administration
|
||||
==============
|
||||
|
||||
.. _extension-configuration:
|
||||
|
||||
Extension Configuration
|
||||
=======================
|
||||
|
||||
Some global settings of the extension may be configured in `Settings -> Extension Configuration -> ods_osm`.
|
||||
|
||||
Screenshot
|
||||
----------
|
||||
|
||||
.. figure:: /Images/ExtensionConfiguration.png
|
||||
:class: with-shadow
|
||||
:alt: Screenshot with first part of the ods_osm settings in the extension configuration
|
||||
|
||||
Screenshot of the ods_osm Extension Configuration
|
||||
|
||||
Reference
|
||||
---------
|
||||
|
||||
+----------------------------+------------------------------------------------+-------------+
|
||||
| Option | Description | Default |
|
||||
+============================+================================================+=============+
|
||||
| Autocomplete longitude | You can enable to search the coordinates on | 1: If no |
|
||||
| and latitude | geonames.org when saving an fe_users or | coordinates |
|
||||
| | tt_address element. | are set |
|
||||
+----------------------------+------------------------------------------------+-------------+
|
||||
| Use service to find | Use this service to get the coordinates of an | 2: |
|
||||
| coordinates | address. If you select “Only cache” you have to| Nominatim |
|
||||
| | fill the cache table manually. If you select a | |
|
||||
| | provider here, be aware that the fields “zip”, | |
|
||||
| | “city” and “country” of every address record | |
|
||||
| | you save is sent to the provider. | |
|
||||
+----------------------------+------------------------------------------------+-------------+
|
||||
| Geo service contact email | Enter a contact email address for the service | |
|
||||
| | provider here. If not specified, email address | |
|
||||
| | of server admin is used. | |
|
||||
+----------------------------+------------------------------------------------+-------------+
|
||||
| Geo service user name | The GeoNames service requires a username | |
|
||||
+----------------------------+------------------------------------------------+-------------+
|
||||
| Default country | Two letter countrycode used in search if no | DE |
|
||||
| | country is specified. | |
|
||||
+----------------------------+------------------------------------------------+-------------+
|
||||
| Enable address search cache| The result of the geo service is stored in | 1 |
|
||||
| | tx_odsosm_geocache if activated. | |
|
||||
+----------------------------+------------------------------------------------+-------------+
|
||||
| Use local javascripts and | Activate this if you don't like to use the | 1 |
|
||||
| images | javascript files from CDNs but the local ones | |
|
||||
| | from this extension. | |
|
||||
+----------------------------+------------------------------------------------+-------------+
|
||||
| Default longitude | | 10.41 |
|
||||
+----------------------------+------------------------------------------------+-------------+
|
||||
| Default latitude | | 51.27 |
|
||||
+----------------------------+------------------------------------------------+-------------+
|
||||
| Default zoom | | 8 |
|
||||
+----------------------------+------------------------------------------------+-------------+
|
||||
|
||||
|
||||
.. _typoscript-configuration:
|
||||
|
||||
TypoScript Configuration
|
||||
========================
|
||||
|
||||
It is mandatory to include the ods_osm TypoScript template "Template OpenStreetMap".
|
||||
This template sets some default values for the ods_osm plugin. The defaults may be configured
|
||||
with the TypoScript Constant Editor.
|
||||
|
||||
With these TypoScript defaults, the editor does not need to make a detailed configuration of the
|
||||
ods_osm plugin. Selecting the wanted marker is suffician.
|
||||
|
||||
The dimenions of the map, the right JavaScript library and zoom level are set by the defaults.
|
||||
But editors may set and overwrite the defaults in the plugin settings.
|
||||
|
||||
|
||||
Reference
|
||||
---------
|
||||
|
||||
.. |mpi| replace:: marker_popup_initial
|
||||
.. |sls| replace:: show_layerswitcher
|
||||
.. |uconm| replace:: use_coords_only_nomarker
|
||||
|
||||
.. |ol| replace:: openlayers
|
||||
|
||||
+-----------------+-----------+-------------------------------------+---------+
|
||||
| Property | Data type | Description | Default |
|
||||
+=================+===========+=====================================+=========+
|
||||
| cluster | boolean | Cluster marker at lower map zoom. | 0 |
|
||||
+-----------------+-----------+-------------------------------------+---------+
|
||||
| cluster_radius | integer | Cluster marker in given radius. | 80 |
|
||||
+-----------------+-----------+-------------------------------------+---------+
|
||||
| external_control| boolean || Allow control with GET or POST | 0 |
|
||||
| | || lon: Map center longitude | |
|
||||
| | || lat: Map center latitudezoom: Map | |
|
||||
| | | zoom level | |
|
||||
| | || layers: Comma separated list of | |
|
||||
| | | tx_odsosm_layer uid's | |
|
||||
| | || records: Comma separated list of | |
|
||||
| | | markers | |
|
||||
| | || Don't forget to set no_cache=1 | |
|
||||
+-----------------+-----------+-------------------------------------+---------+
|
||||
| height | integer | Height of the map div block. This | 80vh |
|
||||
| | | depends on your webdesign. The | |
|
||||
| | | default value is 80vh which means | |
|
||||
| | | 80% from current view port. | |
|
||||
| | | | |
|
||||
| | | You can set other values like | |
|
||||
| | | "80%", 480, 480px | |
|
||||
+-----------------+-----------+-------------------------------------+---------+
|
||||
| icon | IMAGE or | Default marker image | Library |
|
||||
| | TEXT | | default |
|
||||
| | object | | |
|
||||
+-----------------+-----------+-------------------------------------+---------+
|
||||
| JSlibrary | string | JavaScript library: none / jquery | none |
|
||||
+-----------------+-----------+-------------------------------------+---------+
|
||||
| layer | integer || Comma separated list of | 1 |
|
||||
| | list | tx_odsosm_layer uid's. | |
|
||||
| | || 1: Mapnik | |
|
||||
| | || 2: SLUB Renderer | |
|
||||
| | || 3: CycleMap | |
|
||||
| | || 13: ÖPNV Deutschland | |
|
||||
| | || 14: Hike & Bike Map | |
|
||||
| | || 15: Hillshading (NASA SRTM3 v2) | |
|
||||
| | || 17: Hiking routes | |
|
||||
| | || 18: Mapnik BW | |
|
||||
| | || 19: MapSurfer.Net Road | |
|
||||
| | || 20: MapSurfer.Net Topographic | |
|
||||
| | || 21: MapSurfer.Net Hybrid | |
|
||||
| | || 25: TransportMap | |
|
||||
| | || 28: Cycling routes | |
|
||||
| | || 29: Stamen Toner | |
|
||||
| | || 30: Stamen Watercolor | |
|
||||
| | || 31: Public Transport Lines | |
|
||||
| | || 32: Stamen Terrain Labels | |
|
||||
| | || 33: Railway Infrastructure | |
|
||||
+-----------------+-----------+-------------------------------------+---------+
|
||||
| library | string | Library: leaflet / openlayers / | |ol| |
|
||||
| | | openlayers3 / static | |
|
||||
+-----------------+-----------+-------------------------------------+---------+
|
||||
| marker | array with| Tablenames and a comma separated | see m_ |
|
||||
| | table name| list of record ids. | |
|
||||
| | and | | |
|
||||
| | integer | | |
|
||||
| | list | | |
|
||||
+-----------------+-----------+-------------------------------------+---------+
|
||||
| |mpi| | integer | Open popup of this marker | |
|
||||
+-----------------+-----------+-------------------------------------+---------+
|
||||
| no_marker | boolean || If no marker is set: | 1 |
|
||||
| | || 0: Hide map | |
|
||||
| | || 1: Show map | |
|
||||
+-----------------+-----------+-------------------------------------+---------+
|
||||
| popup | TS object | There are two additional fields: | see p_ |
|
||||
| | | “group_title” and | |
|
||||
| | | “group_description” filled with | |
|
||||
| | | group information. | |
|
||||
+-----------------+-----------+-------------------------------------+---------+
|
||||
| position | boolean | Get current user postion from | 0 |
|
||||
| | | browser to center the map. | |
|
||||
+-----------------+-----------+-------------------------------------+---------+
|
||||
| |sls| | boolean | | 0 |
|
||||
+-----------------+-----------+-------------------------------------+---------+
|
||||
| show_popups | boolean || 0:No | 0 |
|
||||
| | || 1:Click | |
|
||||
| | || 2:Hover | |
|
||||
+-----------------+-----------+-------------------------------------+---------+
|
||||
| show_scalebar | boolean | Show a scale line on the map. | 0 |
|
||||
+-----------------+-----------+-------------------------------------+---------+
|
||||
| |uconm| | boolean | Use the default coordinates only if | 0 |
|
||||
| | | no marker exists. | |
|
||||
+-----------------+-----------+-------------------------------------+---------+
|
||||
| width | integer | Height of the map div block. This | 80vw |
|
||||
| | | depends on your webdesign. The | |
|
||||
| | | default value is 80vw which means | |
|
||||
| | | 80% from current view port. | |
|
||||
| | | | |
|
||||
| | | You can set other values like | |
|
||||
| | | "100%", 640, 640px | |
|
||||
+-----------------+-----------+-------------------------------------+---------+
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
::
|
||||
|
||||
plugin.tx_odsosm_pi1 {
|
||||
width = 800
|
||||
height = 600
|
||||
mouse_position = 1
|
||||
}
|
||||
|
||||
.. _m:
|
||||
|
||||
Markers
|
||||
```````
|
||||
|
||||
.. code-block:: typoscript
|
||||
|
||||
plugin.tx_odsosm_pi1 {
|
||||
marker {
|
||||
pages =
|
||||
fe_users =
|
||||
fe_groups =
|
||||
tx_odsosm_track =
|
||||
}
|
||||
}
|
||||
|
||||
.. _p:
|
||||
|
||||
Popups
|
||||
``````
|
||||
|
||||
.. code-block:: typoscript
|
||||
|
||||
plugin.tx_odsosm_pi1 {
|
||||
popup {
|
||||
fe_users = COA
|
||||
fe_users {
|
||||
9 = FILES
|
||||
9 {
|
||||
references {
|
||||
table = fe_users
|
||||
fieldName = image
|
||||
}
|
||||
renderObj = IMAGE
|
||||
renderObj {
|
||||
file {
|
||||
import.data = file:current:uid
|
||||
treatIdAsReference = 1
|
||||
width = 150c
|
||||
height = 150c
|
||||
}
|
||||
altText.data = file:current:alternative
|
||||
titleText.data = file:current:title
|
||||
stdWrap.typolink.parameter.data = file:current:link
|
||||
}
|
||||
}
|
||||
10 = TEXT
|
||||
10 {
|
||||
field = name
|
||||
wrap = <h2>|</h2>
|
||||
override = {field:first_name} {field:middle_name} {field:last_name}
|
||||
override.insertData = 1
|
||||
override.if.isFalse.field = name
|
||||
}
|
||||
20 = TEXT
|
||||
20.field = description
|
||||
20.htmlSpecialChars = 1
|
||||
}
|
||||
tt_address = COA
|
||||
tt_address {
|
||||
9 = FILES
|
||||
9 {
|
||||
references {
|
||||
table = tt_address
|
||||
fieldName = image
|
||||
}
|
||||
renderObj = IMAGE
|
||||
renderObj {
|
||||
file {
|
||||
import.data = file:current:uid
|
||||
treatIdAsReference = 1
|
||||
width = 150c
|
||||
height = 150c
|
||||
}
|
||||
altText.data = file:current:alternative
|
||||
titleText.data = file:current:title
|
||||
stdWrap.typolink.parameter.data = file:current:link
|
||||
}
|
||||
}
|
||||
10 = TEXT
|
||||
10.field = name
|
||||
10.wrap = <h2>|</h2>
|
||||
20 = TEXT
|
||||
20.field = description
|
||||
20.htmlSpecialChars = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Icon Property
|
||||
`````````````
|
||||
|
||||
.. code-block:: typoscript
|
||||
|
||||
plugin.tx_odsosm_pi1 {
|
||||
icon {
|
||||
# IMAGE example
|
||||
fe_users = IMAGE
|
||||
fe_users {
|
||||
file = fileadmin/icon.png
|
||||
file.width = 60px
|
||||
}
|
||||
|
||||
# HTML example
|
||||
fe_users = TEXT
|
||||
fe_users {
|
||||
value = <span>X</span>
|
||||
size_x=20
|
||||
size_y=30
|
||||
offset_x=10
|
||||
offset_y=15
|
||||
}
|
||||
}
|
||||
}
|
||||
197
typo3conf/ext/ods_osm/Documentation/Editors/Index.rst
Normal file
@@ -0,0 +1,197 @@
|
||||
Users manual
|
||||
============
|
||||
|
||||
Frontend Plugin
|
||||
---------------
|
||||
Insert the OpenStreetMap as frontend plugin and define at least one marker to show.
|
||||
The map will center to the average coordinates of the markers.
|
||||
|
||||
.. image:: ../Images/FrontendPlugin.png
|
||||
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Plugin option (TS option) | Description |
|
||||
+============================+================================================+
|
||||
| Marker to show (marker) | Show these records on the map. |
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Cluster markers (cluster) | Group nearby markers. |
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Width (width) | Width of the map in pixels. |
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Height (height) | Height of the map in pixels. |
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Longitude (lon) | Default longitude. |
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Latitude (lat) | Default latitude. |
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Use this coordinates only | If unset, the map is always centered at the |
|
||||
| if no marker exists | given coordinates. If set, the map is only |
|
||||
| (use_coords_only_nomarker) | centered there if no marker exists. |
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Zoom (zoom) | Zoom level. |
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Library (library) | Choose between openlayers, leaflet or static. |
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Base layer (layer) | Show this map. The user can switch between |
|
||||
| | these base layers if the layerswitcher is |
|
||||
| | is enabled. |
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Show popups (show_popups) | Show a popup window with record information if |
|
||||
| | the user hover or click a marker. |
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Show this marker's popup | Open this marker's popup if the user visit the |
|
||||
| initially | map. |
|
||||
| (marker_popup_initial) | |
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Mouse position | Show position of current mouse cursor. |
|
||||
| (mouse_position) | |
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Show layerswitcher | Show layerswitcher which allows the user to |
|
||||
| (show_layerswitcher) | hide markers from the same group. |
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Show scalebar | Show pan/zoom element. |
|
||||
| (show_scalebar) | |
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Show current position | Center the map on the current position of the |
|
||||
| (position) | user (if available) |
|
||||
+----------------------------+------------------------------------------------+
|
||||
|
||||
New elements
|
||||
------------
|
||||
|
||||
Layer
|
||||
.....
|
||||
|
||||
You can define your own layers on root level.
|
||||
|
||||
.. image:: ../Images/Layer.png
|
||||
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Element option | Description |
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Title | Title of this layer. Shown in layerswitcher. |
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Is overlay | Base layer or overlay layer? |
|
||||
+----------------------------+------------------------------------------------+
|
||||
| JavaScript || JavaScript part to create this layer. |
|
||||
| || ###TITLE###: Title of layer. |
|
||||
| || ###VISIBLE###: Contains “'visible':true” if |
|
||||
| | is overlay and no layerswitcher activated. |
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Static map URL || Download static map from this URL. |
|
||||
| || ###lat###: Latitude of map center. |
|
||||
| || ###lon###: Longitude of map center. |
|
||||
| || ###zoom###: Zoom level. |
|
||||
| || ###width###: Image width. |
|
||||
| || ###height###: Image height. |
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Tile URL | URL to fetch tiles. |
|
||||
| | Used by OpenLayers if no JavaScript defined. |
|
||||
| | Used by leaflet. |
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Maximum zoom | Maximum zoom level of this layer. |
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Subdomains | Tile URL subdomains (Variable {s}) |
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Attribution | Attribution text of this layer. |
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Homepage | Homepage URL of this layer. |
|
||||
+----------------------------+------------------------------------------------+
|
||||
|
||||
Marker
|
||||
......
|
||||
|
||||
.. image:: ../Images/Marker.png
|
||||
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Element option | Description |
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Title | Title for this track. Only shown in backend. |
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Icon | Icon file. |
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Size | The size of the icon. Would determined |
|
||||
| | automatically on save. |
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Offset | The offset of the icon. It describes the |
|
||||
| | arrowhead. Would automatically choose the |
|
||||
| | middle bottom of the image. |
|
||||
+----------------------------+------------------------------------------------+
|
||||
|
||||
Track
|
||||
.....
|
||||
|
||||
.. image:: ../Images/OdsOsmRecordTrack.png
|
||||
:width: 820px
|
||||
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Element option | Description |
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Title | Title for this track. Shown in layerswitcher. |
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Color | Color of the track line in the map. |
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Width | Width of the track line. |
|
||||
+----------------------------+------------------------------------------------+
|
||||
| File | Select only one gpx file here. |
|
||||
+----------------------------+------------------------------------------------+
|
||||
|
||||
Vector
|
||||
......
|
||||
|
||||
You can add GeoJSON data and/or a GeoJSON file to display on a new layer. The
|
||||
GeoJSON may contain FeatureCollections. Polygone, Lines and Points are tested
|
||||
and are supported by the vector draw wizard.
|
||||
|
||||
.. image:: ../Images/OdsOsmRecordVectorData.png
|
||||
:width: 820px
|
||||
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Element option | Description |
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Title | Title for this vector. Shown in layerswitcher. |
|
||||
+----------------------------+------------------------------------------------+
|
||||
| GeoJSON | Fill GeoJSON data and/or select a GeoJSON file |
|
||||
| | below. |
|
||||
| | You can use the vector draw wizard to create |
|
||||
| | and edit the GeoJSON data in this field. |
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Color | Color of the vector line in the map (optional).|
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Width | Width of the vector polyline. (optional) |
|
||||
+----------------------------+------------------------------------------------+
|
||||
| File | Select only one geojson file here. |
|
||||
+----------------------------+------------------------------------------------+
|
||||
|
||||
Extended elements
|
||||
-----------------
|
||||
|
||||
Website user
|
||||
............
|
||||
|
||||
.. figure:: /Images/FeUserCoordinates.png
|
||||
:class: with-shadow
|
||||
:alt: Part of the form of a fe_users record with fields for longitude and latitude.
|
||||
|
||||
Fields for longitude and latitude of a fe_users record. Click on the OSM icon to launch the map wizard.
|
||||
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Element option | Description |
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Longitude and Latitude | Enter the coordinates of an address here. It |
|
||||
| | would determined automatically if zip or city |
|
||||
| | is set and autocompletion is enabled in the |
|
||||
| | extension manager. |
|
||||
| | Use the OpenStreetMap icon to search the |
|
||||
| | coordinates on the map. |
|
||||
+----------------------------+------------------------------------------------+
|
||||
|
||||
Website usergroup
|
||||
.................
|
||||
|
||||
.. image:: ../Images/Icon.png
|
||||
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Element option | Description |
|
||||
+----------------------------+------------------------------------------------+
|
||||
| Marker | Optionally specify a marker here. |
|
||||
+----------------------------+------------------------------------------------+
|
||||
|
After Width: | Height: | Size: 206 KiB |
|
After Width: | Height: | Size: 1.9 MiB |
|
After Width: | Height: | Size: 171 KiB |
BIN
typo3conf/ext/ods_osm/Documentation/Images/FeUserCoordinates.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
typo3conf/ext/ods_osm/Documentation/Images/FrontendExample.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
typo3conf/ext/ods_osm/Documentation/Images/FrontendPlugin.png
Normal file
|
After Width: | Height: | Size: 141 KiB |
BIN
typo3conf/ext/ods_osm/Documentation/Images/Icon.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
typo3conf/ext/ods_osm/Documentation/Images/Layer.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
typo3conf/ext/ods_osm/Documentation/Images/Marker.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
typo3conf/ext/ods_osm/Documentation/Images/OdsOsmRecordTrack.png
Normal file
|
After Width: | Height: | Size: 162 KiB |
|
After Width: | Height: | Size: 155 KiB |
BIN
typo3conf/ext/ods_osm/Documentation/Images/RecordsToShow.png
Normal file
|
After Width: | Height: | Size: 308 KiB |
14
typo3conf/ext/ods_osm/Documentation/Includes.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
.. This is 'Includes.txt'. It is included at the very top of each and
|
||||
every ReST source file in THIS documentation project (= manual).
|
||||
|
||||
.. role:: aspect (emphasis)
|
||||
.. role:: html(code)
|
||||
.. role:: js(code)
|
||||
.. role:: php(code)
|
||||
.. role:: typoscript(code)
|
||||
|
||||
.. role:: ts(typoscript)
|
||||
:class: typoscript
|
||||
|
||||
.. default-role:: code
|
||||
.. highlight:: php
|
||||
42
typo3conf/ext/ods_osm/Documentation/Index.rst
Normal file
@@ -0,0 +1,42 @@
|
||||
|
||||
.. include:: Includes.txt
|
||||
|
||||
.. _Start:
|
||||
|
||||
============================
|
||||
EXT: ods_osm (OpenStreetMap)
|
||||
============================
|
||||
|
||||
:Extension key:
|
||||
ods_osm
|
||||
|
||||
:Package name:
|
||||
bobosch/ods-osm
|
||||
|
||||
:Version:
|
||||
|release|
|
||||
|
||||
:Language:
|
||||
en
|
||||
|
||||
:Author:
|
||||
Robert Heel <typo3@bobosch.de>, Alexander Bigga <alexander@bigga.de>
|
||||
|
||||
:License:
|
||||
GPL 3.0
|
||||
|
||||
:Rendered:
|
||||
|today|
|
||||
|
||||
:Description:
|
||||
Add an interactive OpenStreetMap map to your website.
|
||||
Can also show other tile based maps with OpenLayers or Leaflet.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:glob:
|
||||
|
||||
Introduction/Index
|
||||
Editors/Index
|
||||
Administrators/Index
|
||||
Tutorial/Index
|
||||
45
typo3conf/ext/ods_osm/Documentation/Introduction/Index.rst
Normal file
@@ -0,0 +1,45 @@
|
||||
Introduction
|
||||
============
|
||||
|
||||
What does it do?
|
||||
----------------
|
||||
- Show an interactive OpenStreetMap map with OpenLayers or Leaflet.
|
||||
- Store coordinates in fe_users and tt_address tables and show as markers in the map.
|
||||
- Show record information in popup window.
|
||||
- Display gps tracks (GPX, KML).
|
||||
- Display of GeoJSON vector files.
|
||||
|
||||
Screenshots
|
||||
-----------
|
||||
Frontend plugin
|
||||
|
||||
The example shows the output of the frontend plugin with the following settings:
|
||||
|
||||
* Leaflet JavaScript
|
||||
* address of "Max Mustermann" as tt_address record with default marker, clickt on the marker
|
||||
* GPX track with start and stop marker
|
||||
|
||||
.. image:: ../Images/FrontendExample.png
|
||||
|
||||
Demo Instance
|
||||
-------------
|
||||
|
||||
At https://osm.bigga.de a demo instance of EXT:ods_osm is available which presents multiple
|
||||
use cases of this extension.
|
||||
|
||||
Donation
|
||||
--------
|
||||
|
||||
This extension was only possible with the help of many other free projects.
|
||||
|
||||
You're likely using one of the main map “Mapnik”, “Osmarender” or “Cyclemap” - feel free to
|
||||
donate to the OpenStreetMap project https://supporting.openstreetmap.org/donate/
|
||||
|
||||
If you are using the address search (autocomplete longitude and latitude in address records),
|
||||
please donate the service you use:
|
||||
|
||||
Geonames: https://www.geonames.org/donations.html or buy some credits there.
|
||||
|
||||
Nominatim: https://supporting.openstreetmap.org/donate/
|
||||
|
||||
And don't forget the main components: https://typo3.org/ and https://openlayers.org/ or https://leaflet.org/
|
||||
18
typo3conf/ext/ods_osm/Documentation/Settings.cfg
Normal file
@@ -0,0 +1,18 @@
|
||||
[general]
|
||||
project = OSM
|
||||
release = 4.2
|
||||
description = Add an interactive OpenStreetMap map to your website.
|
||||
Can also show other OpenLayers compatible maps.
|
||||
|
||||
[html_theme_options]
|
||||
github_repository = bobosch/ods_osm
|
||||
github_branch = master
|
||||
|
||||
project_home = https://github.com/bobosch/ods_osm
|
||||
project_contact = mailto:typo3@bobosch.de
|
||||
project_repository = https://github.com/bobosch/ods_osm
|
||||
project_issues = https://github.com/bobosch/ods_osm/issues
|
||||
project_discussions =
|
||||
|
||||
# leave this empty
|
||||
use_opensearch =
|
||||
59
typo3conf/ext/ods_osm/Documentation/Tutorial/Index.rst
Normal file
@@ -0,0 +1,59 @@
|
||||
Tutorial
|
||||
========
|
||||
|
||||
Install Extensions via Composer
|
||||
-------------------------------
|
||||
|
||||
The following steps are tested with TYPO3 11.5 LTS.
|
||||
|
||||
1. Install ods_osm
|
||||
|
||||
``composer require bobosch/ods-osm:^4.2``
|
||||
|
||||
2. Install tt_address (optional)
|
||||
|
||||
``composer req friendsoftypo3/tt-address``
|
||||
|
||||
|
||||
Configure Extensions
|
||||
--------------------
|
||||
|
||||
1. Include static template "OpenStreetMap" into your root-template
|
||||
2. (optional) Check settings with the TypoScript constant editor. See :ref:`typoscript-configuration`.
|
||||
3. (optional) Check the extension configuration. See :ref:`extension-configuration`.
|
||||
|
||||
|
||||
Create Record
|
||||
-------------
|
||||
|
||||
1. Open or create an ``fe_users`` or ``tt_address`` record.
|
||||
2. Enter zipcode or city and save the record (without closing it).
|
||||
|
||||
.. figure:: /Images/CreateNewAddressRecord.png
|
||||
:class: with-shadow
|
||||
:alt: Screenshot of form to create new address record with input fields for city, postalcode, longitute and latitude
|
||||
|
||||
Example with only ZIP is inserted into tt_address form.
|
||||
|
||||
3. Scroll to the “Longitude” section and use the marker icon to open the map wizard.
|
||||
|
||||
.. figure:: /Images/EditAddressCoordinateWizard.png
|
||||
:class: with-shadow
|
||||
:alt: Screenshot of same tt_address form with coordinate wizard (map view) as modal overlay
|
||||
|
||||
Change latitude and longigute with the map wizard.
|
||||
|
||||
4. Click on the correct position or move the marker and select "Import marker-coordinates".
|
||||
5. Save the record again.
|
||||
|
||||
Place OSM Plugin
|
||||
----------------
|
||||
|
||||
1. Insert a content element plugin "OpenStreetMap" on your page.
|
||||
2. Add your address record in "Records to show”.
|
||||
|
||||
.. figure:: /Images/RecordsToShow.png
|
||||
:class: with-shadow
|
||||
:alt: Screenshot of the OSM plugin settings with selected tt_address record.
|
||||
|
||||
Add tt_address record to OSM plugin field "Records to show".
|
||||
24
typo3conf/ext/ods_osm/README.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# ods_osm
|
||||
|
||||
TYPO3 Extension to show OpenStreetMap maps onto your website.
|
||||
|
||||
## What does it do?
|
||||
|
||||
- Show an interactive OpenStreetMap map with OpenLayers or Leaflet.
|
||||
- Store coordinates in fe_users and tt_address tables and show as markers in the map.
|
||||
- Show record information in popup window.
|
||||
- Display gps tracks.
|
||||
|
||||
## Maintainer
|
||||
|
||||
The extension was developed initially by [Robert Heel](mailto:typo3@bobosch.de) in 2010 for
|
||||
TYPO3 4.5 up to TYPO3 8.7.
|
||||
|
||||
Starting with release 3.0 for TYPO3 9.5 LTS, [Alexander Bigga](https://www.bigga.de) picked
|
||||
up the maintenance of the extension in early 2020. Since then, the extensions has been updated
|
||||
for all major TYPO3 LTS versions.
|
||||
|
||||
## Issues and Feature requests
|
||||
|
||||
If you find a bug, please use the [GitHub issue tracker](https://github.com/bobosch/ods_osm/issues) to get in contact.
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" lang="en"
|
||||
xmlns:f="http://typo3.org/ns/TYPO3/Fluid/ViewHelpers"
|
||||
>
|
||||
<f:layout name="Default"/>
|
||||
<f:section name="Main">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<f:render partial="{index.configuration.partialIdentifier}/Detail" arguments="{index: index}"/>
|
||||
<div class="btn-group">
|
||||
<f:if condition="{settings.listPid}">
|
||||
<f:link.page pageUid="{settings.listPid}" class="btn btn-default">
|
||||
<span class="glyphicon glyphicon-arrow-left"></span>
|
||||
<f:translate key="back"/>
|
||||
</f:link.page>
|
||||
</f:if>
|
||||
<f:link.action action="detail" arguments="{index: index}" format="ics" class="btn btn-default">ICS/iCal</f:link.action>
|
||||
</div>
|
||||
<div class="map">
|
||||
<f:cObject typoscriptObjectPath="plugin.tx_odsosm_pi1" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</f:section>
|
||||
</div>
|
||||
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<file source-language="en" target-language="de" datatype="plaintext" original="messages" date="2021-03-19T20:06:58Z" product-name="ods_osm">
|
||||
<header/>
|
||||
<body>
|
||||
<trans-unit id="pi1_title" xml:space="preserve" approved="yes">
|
||||
<source>OpenStreetMap</source>
|
||||
<target>OpenStreetMap</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="pi1_plus_wiz_description" xml:space="preserve" approved="yes">
|
||||
<source>Add an interactive map to your website.</source>
|
||||
<target>Interaktive Karte zur Website hinzufügen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="wiz_geocode" xml:space="preserve" approved="yes">
|
||||
<source>Geocode addresses</source>
|
||||
<target>Adressen geokodieren</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="openlayers.showLayerList" xml:space="preserve">
|
||||
<source>Show layer list</source>
|
||||
<target>Liste der Kartenebenen</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="openlayers.hideLayerList" xml:space="preserve">
|
||||
<source>Hide layer list</source>
|
||||
<target>Liste der Kartenebenen ausblenden</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="openlayers.clusterLayer" xml:space="preserve">
|
||||
<source>Cluster Layer</source>
|
||||
<target>Cluster Ebene</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="base_layer" xml:space="preserve">
|
||||
<source>Base Layer</source>
|
||||
<target>Grundkarte</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="overlays" xml:space="preserve">
|
||||
<source>Overlays</source>
|
||||
<target>Überlagerungskarten</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="file" xml:space="preserve">
|
||||
<source>File</source>
|
||||
<target>Datei</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="mouse_position" xml:space="preserve">
|
||||
<source>Mouse position</source>
|
||||
<target>Mausposition</target>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
@@ -0,0 +1,373 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<xliff version="1.0">
|
||||
<file source-language="en" target-language="de" datatype="plaintext" original="messages" date="2023-08-16T19:15:41Z">
|
||||
<header>
|
||||
<generator>LFEditor</generator>
|
||||
</header>
|
||||
<body>
|
||||
<trans-unit id="coordinatepickerWizard" approved="yes">
|
||||
<source><![CDATA[Coordinate Picker Wizard]]></source>
|
||||
<target><![CDATA[Kartenassistent für Auswahl der Koordinaten]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="coordinatepickerWizard.close" approved="yes">
|
||||
<source><![CDATA[Close Coordinate Picker Wizard]]></source>
|
||||
<target><![CDATA[Kartenassistent schließen]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="coordinatepickerWizard.import" approved="yes">
|
||||
<source><![CDATA[Import Marker Coordinates]]></source>
|
||||
<target><![CDATA[Marker Koordinaten importieren]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="coordinatepickerWizard.title" approved="yes">
|
||||
<source><![CDATA[Search coordinates]]></source>
|
||||
<target><![CDATA[Kartenassistent für Auswahl der Koordinaten]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_address_group.tx_odsosm_marker" approved="yes">
|
||||
<source><![CDATA[Marker]]></source>
|
||||
<target><![CDATA[Marker]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.list_type_pi1" approved="yes">
|
||||
<source><![CDATA[OpenStreetMap]]></source>
|
||||
<target><![CDATA[OpenStreetMap]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.cluster" approved="yes">
|
||||
<source><![CDATA[Cluster markers]]></source>
|
||||
<target><![CDATA[Markierungen bündeln]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.cluster_radius" approved="yes">
|
||||
<source><![CDATA[Cluster radius]]></source>
|
||||
<target><![CDATA[Radius des Marker Clusters]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.enable_dragging" approved="yes">
|
||||
<source><![CDATA[Enable dragging with mouse and touch]]></source>
|
||||
<target><![CDATA[Karte mit Maus bzw. Touch verschieben]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.enable_scrollwheelzoom" approved="yes">
|
||||
<source><![CDATA[Enable zooming with mouse scroll wheel]]></source>
|
||||
<target><![CDATA[Zoomen mit dem Mausrad]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.height" approved="yes">
|
||||
<source><![CDATA[Height]]></source>
|
||||
<target><![CDATA[Höhe]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.layer" approved="yes">
|
||||
<source><![CDATA[Base layer]]></source>
|
||||
<target><![CDATA[Hauptebene]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.layerswitcher_activationMode" approved="yes">
|
||||
<source><![CDATA[Layerswitcher Activation Mode]]></source>
|
||||
<target><![CDATA[Methode zum Aufklappen des Ebenenumschalter]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.library" approved="yes">
|
||||
<source><![CDATA[Library]]></source>
|
||||
<target><![CDATA[Programm]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.marker" approved="yes">
|
||||
<source><![CDATA[Records to show]]></source>
|
||||
<target><![CDATA[Markierungen anzeigen]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.marker.description" approved="yes">
|
||||
<source><![CDATA[Select marker, track or vector records to show on the map.]]></source>
|
||||
<target><![CDATA[Marker, Track oder Vector-Daten für die Anzeige auf der Karte wählen.]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.marker_popup_intial" approved="yes">
|
||||
<source><![CDATA[Show this marker's popup initially]]></source>
|
||||
<target><![CDATA[Markierungspopup anfangs anzeigen]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.mouse_position" approved="yes">
|
||||
<source><![CDATA[Show mouse position]]></source>
|
||||
<target><![CDATA[Zeige Mausposition]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.overlays.description" approved="yes" xml:space="preserve">
|
||||
<source><![CDATA[The following overlays are available in the frontend.
|
||||
If using the layer switcher, the selected overlays may be toggled on/off. The initial state is selected by "overlays_active".
|
||||
Without layer switcher, all overlays are active in the map.
|
||||
]]></source>
|
||||
<target><![CDATA[Die folgenden Überlagerungskarten stehen im Frontend zur Verfügung. Wenn der Ebenumschalter erwendet wird, können diese Ebenen ein- und ausgeschaltet werden. Die initiale Aktivierung kann mit der folgenden Einstellung ("Überlagerungskarten aktivieren") gesteuert werden. Ohne Ebenenumschalter werden alle Ebenen angezeigt.]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.overlays_active" approved="yes">
|
||||
<source><![CDATA[Activated overlays]]></source>
|
||||
<target><![CDATA[Überlagerungskarten aktivieren]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.overlays_active.description" approved="yes">
|
||||
<source><![CDATA[The following overlays are activated in the layer switcher initially.]]></source>
|
||||
<target><![CDATA[Die folgenden Überlagerungskarten sind beim Laden der Karte aktiviert.]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.position_show" approved="yes">
|
||||
<source><![CDATA[Show current position]]></source>
|
||||
<target><![CDATA[Aktuelle Position anzeigen]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.sheet_sDEF" approved="yes">
|
||||
<source><![CDATA[Default]]></source>
|
||||
<target><![CDATA[Standard]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.show_fullscreen" approved="yes">
|
||||
<source><![CDATA[Show Fullscreen Button]]></source>
|
||||
<target><![CDATA[Vollbild anzeigen]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.show_layerswitcher" approved="yes">
|
||||
<source><![CDATA[Show layerswitcher]]></source>
|
||||
<target><![CDATA[Ebenenumschalter anzeigen]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.show_layerswitcher.I.0" approved="yes">
|
||||
<source><![CDATA[No]]></source>
|
||||
<target><![CDATA[Nein]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.show_layerswitcher.I.1" approved="yes">
|
||||
<source><![CDATA[Closed]]></source>
|
||||
<target><![CDATA[Geschlossen]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.show_layerswitcher.I.2" approved="yes">
|
||||
<source><![CDATA[Opened]]></source>
|
||||
<target><![CDATA[Geöffnet]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.show_popups" approved="yes">
|
||||
<source><![CDATA[Show popups]]></source>
|
||||
<target><![CDATA[Popups anzeigen]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.show_popups.I.0" approved="yes">
|
||||
<source><![CDATA[No]]></source>
|
||||
<target><![CDATA[Nein]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.show_popups.I.1" approved="yes">
|
||||
<source><![CDATA[Click]]></source>
|
||||
<target><![CDATA[Click]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.show_popups.I.2" approved="yes">
|
||||
<source><![CDATA[Hover]]></source>
|
||||
<target><![CDATA[Hover]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.show_scalebar" approved="yes">
|
||||
<source><![CDATA[Show ScaleBar]]></source>
|
||||
<target><![CDATA[Massstabsanzeige anzeigen]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.use_coords_only_nomarker" approved="yes">
|
||||
<source><![CDATA[Use this coordinates only if no marker exists]]></source>
|
||||
<target><![CDATA[Diese Koordinaten nur verwenden wenn keine Markierung existiert]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.width" approved="yes">
|
||||
<source><![CDATA[Width]]></source>
|
||||
<target><![CDATA[Breite]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.zoom" approved="yes">
|
||||
<source><![CDATA[Zoom]]></source>
|
||||
<target><![CDATA[Zoom]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_geocache" approved="yes">
|
||||
<source><![CDATA[Geocache]]></source>
|
||||
<target><![CDATA[Geocache]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_geocache.cache_hit" approved="yes">
|
||||
<source><![CDATA[Hit from cache]]></source>
|
||||
<target><![CDATA[Hit from cache]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_geocache.city" approved="yes">
|
||||
<source><![CDATA[City]]></source>
|
||||
<target><![CDATA[Stadt]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_geocache.country" approved="yes">
|
||||
<source><![CDATA[Country]]></source>
|
||||
<target><![CDATA[Land]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_geocache.housenumber" approved="yes">
|
||||
<source><![CDATA[Housenumber]]></source>
|
||||
<target><![CDATA[Hausnummer]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_geocache.lat" approved="yes">
|
||||
<source><![CDATA[Latitude]]></source>
|
||||
<target><![CDATA[Breitengrad]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_geocache.lon" approved="yes">
|
||||
<source><![CDATA[Longitude]]></source>
|
||||
<target><![CDATA[Längengrad]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_geocache.service_hit" approved="yes">
|
||||
<source><![CDATA[Hit from location service]]></source>
|
||||
<target><![CDATA[Hit from location service]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_geocache.state" approved="yes">
|
||||
<source><![CDATA[State]]></source>
|
||||
<target><![CDATA[Bundesland]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_geocache.street" approved="yes">
|
||||
<source><![CDATA[Street]]></source>
|
||||
<target><![CDATA[Straße]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_geocache.zip" approved="yes">
|
||||
<source><![CDATA[Zip]]></source>
|
||||
<target><![CDATA[PLZ]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_lat" approved="yes">
|
||||
<source><![CDATA[Latitude]]></source>
|
||||
<target><![CDATA[Breitengrad]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer" approved="yes">
|
||||
<source><![CDATA[Layer]]></source>
|
||||
<target><![CDATA[Ebene]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer.attribution" approved="yes">
|
||||
<source><![CDATA[Attribution]]></source>
|
||||
<target><![CDATA[Attribution]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer.homepage" approved="yes">
|
||||
<source><![CDATA[Homepage]]></source>
|
||||
<target><![CDATA[Homepage]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer.javascript_include" approved="yes">
|
||||
<source><![CDATA[Include static JavaScript]]></source>
|
||||
<target><![CDATA[Statisches JavaScript einbinden]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer.javascript_openlayers" approved="yes">
|
||||
<source><![CDATA[JavaScript for OpenLayers]]></source>
|
||||
<target><![CDATA[JavaScript für OpenLayers]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer.max_zoom" approved="yes">
|
||||
<source><![CDATA[Maximum zoom]]></source>
|
||||
<target><![CDATA[Maximaler Zoom]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer.min_zoom" approved="yes">
|
||||
<source><![CDATA[Minimum zoom]]></source>
|
||||
<target><![CDATA[Minimaler zoom]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer.overlay" approved="yes">
|
||||
<source><![CDATA[Is overlay]]></source>
|
||||
<target><![CDATA[Ist Overlay]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer.static_url" approved="yes">
|
||||
<source><![CDATA[Static map URL]]></source>
|
||||
<target><![CDATA[URL für statische Karte]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer.subdomains" approved="yes">
|
||||
<source><![CDATA[Subdomains]]></source>
|
||||
<target><![CDATA[Subdomains]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer.tile_https" approved="yes">
|
||||
<source><![CDATA[Tile URL https available]]></source>
|
||||
<target><![CDATA[Tile URL https verfügbar]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer.tile_url" approved="yes">
|
||||
<source><![CDATA[Tile URL]]></source>
|
||||
<target><![CDATA[Tile URL]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer.title" approved="yes">
|
||||
<source><![CDATA[Title]]></source>
|
||||
<target><![CDATA[Titel]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_lon" approved="yes">
|
||||
<source><![CDATA[Longitude]]></source>
|
||||
<target><![CDATA[Längengrad]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_marker" approved="yes">
|
||||
<source><![CDATA[Marker]]></source>
|
||||
<target><![CDATA[Marker]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_marker.icon" approved="yes">
|
||||
<source><![CDATA[Icon]]></source>
|
||||
<target><![CDATA[Icon]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_marker.offset_x" approved="yes">
|
||||
<source><![CDATA[Offset X]]></source>
|
||||
<target><![CDATA[Ausgleich X]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_marker.offset_y" approved="yes">
|
||||
<source><![CDATA[Offset Y]]></source>
|
||||
<target><![CDATA[Ausgleich Y]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_marker.size_x" approved="yes">
|
||||
<source><![CDATA[Size X]]></source>
|
||||
<target><![CDATA[Größe X]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_marker.size_y" approved="yes">
|
||||
<source><![CDATA[Size Y]]></source>
|
||||
<target><![CDATA[Größe Y]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_marker.title" approved="yes">
|
||||
<source><![CDATA[Title]]></source>
|
||||
<target><![CDATA[Titel]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_track" approved="yes">
|
||||
<source><![CDATA[Track]]></source>
|
||||
<target><![CDATA[Track]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_track.color" approved="yes">
|
||||
<source><![CDATA[Color]]></source>
|
||||
<target><![CDATA[Farbe]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_track.file" approved="yes">
|
||||
<source><![CDATA[File]]></source>
|
||||
<target><![CDATA[Datei]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_track.file.add" approved="yes">
|
||||
<source><![CDATA[Add track file]]></source>
|
||||
<target><![CDATA[Track-Datei hinzufügen]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_track.max_lat" approved="yes">
|
||||
<source><![CDATA[Maximum Latitude]]></source>
|
||||
<target><![CDATA[Maximaler Breitengrad]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_track.max_lon" approved="yes">
|
||||
<source><![CDATA[Maximum Longitude]]></source>
|
||||
<target><![CDATA[Maximaler Längengrad]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_track.min_lat" approved="yes">
|
||||
<source><![CDATA[Minimum Latitude]]></source>
|
||||
<target><![CDATA[Minimaler Breitengrad]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_track.min_lon" approved="yes">
|
||||
<source><![CDATA[Minumum Longitude]]></source>
|
||||
<target><![CDATA[Minimaler Längengrad]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_track.title" approved="yes">
|
||||
<source><![CDATA[Title]]></source>
|
||||
<target><![CDATA[Titel]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_track.width" approved="yes">
|
||||
<source><![CDATA[Width]]></source>
|
||||
<target><![CDATA[Breite]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_vector" approved="yes">
|
||||
<source><![CDATA[Vector]]></source>
|
||||
<target><![CDATA[Vektor]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_vector.data" approved="yes">
|
||||
<source><![CDATA[GeoJSON]]></source>
|
||||
<target><![CDATA[GeoJSON]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_vector.file" approved="yes">
|
||||
<source><![CDATA[File]]></source>
|
||||
<target><![CDATA[Datei]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_vector.file.add" approved="yes">
|
||||
<source><![CDATA[Add geo data file]]></source>
|
||||
<target><![CDATA[GeoJSON-Datei hinzufügen]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_vector.properties" approved="yes">
|
||||
<source><![CDATA[Properties to show in popup]]></source>
|
||||
<target><![CDATA[Eigenschaften, die im Popup ausgegeben werden sollen]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_vector.properties_from_file" approved="yes">
|
||||
<source><![CDATA[Read properties from file]]></source>
|
||||
<target><![CDATA[Lese Eigenschaften aus der Datei]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_vector.title" approved="yes">
|
||||
<source><![CDATA[Title]]></source>
|
||||
<target><![CDATA[Titel]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="vectordrawWizard" approved="yes">
|
||||
<source><![CDATA[Vector Draw Wizard]]></source>
|
||||
<target><![CDATA[Kartenassitent zum Zeichnen von Vektor-Daten]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="vectordrawWizard.close" approved="yes">
|
||||
<source><![CDATA[Close Vector Draw Wizard]]></source>
|
||||
<target><![CDATA[Kartenassistent schließen]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="vectordrawWizard.import" approved="yes">
|
||||
<source><![CDATA[Import vector data to form]]></source>
|
||||
<target><![CDATA[Vektor-Daten in Formular importieren]]></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="vectordrawWizard.title" approved="yes">
|
||||
<source><![CDATA[Draw vector data and save as GeoJSON]]></source>
|
||||
<target><![CDATA[Vektor-Daten zeichnen und als GeoJSON speichern]]></target>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<file source-language="en" target-language="it" datatype="plaintext" original="messages" date="2021-03-19T20:06:58Z" product-name="ods_osm">
|
||||
<header/>
|
||||
<body>
|
||||
<trans-unit id="pi1_title" xml:space="preserve" approved="yes">
|
||||
<source>OpenStreetMap</source>
|
||||
<target>OpenStreetMap</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="pi1_plus_wiz_description" xml:space="preserve" approved="yes">
|
||||
<source>Add an interactive map to your website.</source>
|
||||
<target>Aggiungi una mappa interattiva al tuo sito web.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="wiz_geocode" xml:space="preserve" approved="yes">
|
||||
<source>Geocode addresses</source>
|
||||
<target>Indirizzi Geocode</target>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
@@ -0,0 +1,288 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<file source-language="en" target-language="it" datatype="plaintext" original="messages" date="2021-03-19T20:06:52Z" product-name="ods_osm">
|
||||
<header/>
|
||||
<body>
|
||||
<trans-unit id="tt_address_group.tx_odsosm_marker" xml:space="preserve" approved="yes">
|
||||
<source>Marker</source>
|
||||
<target>Segnaposto</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.list_type_pi1" xml:space="preserve" approved="yes">
|
||||
<source>OpenStreetMap</source>
|
||||
<target>OpenStreetMap</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.sheet_sDEF" xml:space="preserve" approved="yes">
|
||||
<source>Default</source>
|
||||
<target>Predefinito</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.cluster" xml:space="preserve" approved="yes">
|
||||
<source>Cluster markers</source>
|
||||
<target>Indicatori di gruppo</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.marker" xml:space="preserve" approved="yes">
|
||||
<source>Marker to show</source>
|
||||
<target>Segnaposto da mostrare</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.marker_popup_intial" xml:space="preserve" approved="yes">
|
||||
<source>Show this marker's popup initially</source>
|
||||
<target>Mostra il popup di questo segnaposto all'inizio</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.width" xml:space="preserve" approved="yes">
|
||||
<source>Width</source>
|
||||
<target>Larghezza</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.height" xml:space="preserve" approved="yes">
|
||||
<source>Height</source>
|
||||
<target>Altezza</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.layer" xml:space="preserve" approved="yes">
|
||||
<source>Base layer</source>
|
||||
<target>Strato base</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.library" xml:space="preserve" approved="yes">
|
||||
<source>Library</source>
|
||||
<target>Libreria</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.position_show" xml:space="preserve" approved="yes">
|
||||
<source>Show current position</source>
|
||||
<target>Mostra posizione attuale</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.show_popups" xml:space="preserve" approved="yes">
|
||||
<source>Show popups</source>
|
||||
<target>Mostra popup</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.show_popups.I.1" xml:space="preserve" approved="yes">
|
||||
<source>Click</source>
|
||||
<target>Click</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.show_popups.I.2" xml:space="preserve" approved="yes">
|
||||
<source>Hover</source>
|
||||
<target>Hover</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.show_popups.I.3" xml:space="preserve" approved="yes">
|
||||
<source>Exclusive</source>
|
||||
<target>Esclusivo</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.show_layerswitcher" xml:space="preserve" approved="yes">
|
||||
<source>Show layerswitcher</source>
|
||||
<target>Mostra selettore di livello</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.show_layerswitcher.I.0" xml:space="preserve" approved="yes">
|
||||
<source>No</source>
|
||||
<target>No</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.show_layerswitcher.I.1" xml:space="preserve" approved="yes">
|
||||
<source>Closed</source>
|
||||
<target>Chiuso</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.show_layerswitcher.I.2" xml:space="preserve" approved="yes">
|
||||
<source>Opened</source>
|
||||
<target>Aperto</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.show_scalebar" xml:space="preserve" approved="yes">
|
||||
<source>Show ScaleBar</source>
|
||||
<target>Mostra barra per la scala</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.use_coords_only_nomarker" xml:space="preserve" approved="yes">
|
||||
<source>Use this coordinates only if no marker exists</source>
|
||||
<target>Usa queste coordinate solo se non esiste alcun segnaposto</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.zoom" xml:space="preserve" approved="yes">
|
||||
<source>Zoom</source>
|
||||
<target>Zoom</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.enable_dragging" xml:space="preserve" approved="yes">
|
||||
<source>Enable dragging with mouse and touch</source>
|
||||
<target></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.enable_scrollwheelzoom" xml:space="preserve" approved="yes">
|
||||
<source>Enable zooming with mouse scroll wheel</source>
|
||||
<target></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_lon" xml:space="preserve" approved="yes">
|
||||
<source>Longitude</source>
|
||||
<target>Longitudine</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_lat" xml:space="preserve" approved="yes">
|
||||
<source>Latitude</source>
|
||||
<target>Latitudine</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_geocache" xml:space="preserve" approved="yes">
|
||||
<source>Geocache</source>
|
||||
<target>Geocache</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_geocache.country" xml:space="preserve" approved="yes">
|
||||
<source>Country</source>
|
||||
<target>Nazione</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_geocache.state" xml:space="preserve" approved="yes">
|
||||
<source>State</source>
|
||||
<target>Stato/Provincia</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_geocache.city" xml:space="preserve" approved="yes">
|
||||
<source>City</source>
|
||||
<target>Città</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_geocache.zip" xml:space="preserve" approved="yes">
|
||||
<source>Zip</source>
|
||||
<target>Codice postale</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_geocache.street" xml:space="preserve" approved="yes">
|
||||
<source>Street</source>
|
||||
<target>Via</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_geocache.housenumber" xml:space="preserve" approved="yes">
|
||||
<source>Housenumber</source>
|
||||
<target>Numero civico</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_geocache.lon" xml:space="preserve" approved="yes">
|
||||
<source>Longitude</source>
|
||||
<target>Longitudine</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_geocache.lat" xml:space="preserve" approved="yes">
|
||||
<source>Latitude</source>
|
||||
<target>Latitudine</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_geocache.cache_hit" xml:space="preserve" approved="yes">
|
||||
<source>Hit from cache</source>
|
||||
<target>Risultato dalla cache</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_geocache.service_hit" xml:space="preserve" approved="yes">
|
||||
<source>Hit from location service</source>
|
||||
<target>Risultato dal servizio di localizzazione</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer" xml:space="preserve" approved="yes">
|
||||
<source>Layer</source>
|
||||
<target>Strato</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer.title" xml:space="preserve" approved="yes">
|
||||
<source>Title</source>
|
||||
<target>Titolo</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer.overlay" xml:space="preserve" approved="yes">
|
||||
<source>Is overlay</source>
|
||||
<target>È overlay</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer.javascript_include" xml:space="preserve" approved="yes">
|
||||
<source>Include static JavaScript</source>
|
||||
<target>Includi JavaScript statico</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer.javascript_openlayers" xml:space="preserve" approved="yes">
|
||||
<source>JavaScript for OpenLayers</source>
|
||||
<target>JavaScript per OpenLayers</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer.static_url" xml:space="preserve" approved="yes">
|
||||
<source>Static map URL</source>
|
||||
<target>URL mappa statica</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer.tile_url" xml:space="preserve" approved="yes">
|
||||
<source>Tile URL</source>
|
||||
<target>URL del riquadro</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer.tile_https" xml:space="preserve" approved="yes">
|
||||
<source>Tile URL https available</source>
|
||||
<target>https disponibile per l'URL del riquadro</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer.min_zoom" xml:space="preserve" approved="yes">
|
||||
<source>Minimum zoom</source>
|
||||
<target>Zoom minimo</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer.max_zoom" xml:space="preserve" approved="yes">
|
||||
<source>Maximum zoom</source>
|
||||
<target>Zoom massimo</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer.subdomains" xml:space="preserve" approved="yes">
|
||||
<source>Subdomains</source>
|
||||
<target>Sottodomini</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer.attribution" xml:space="preserve" approved="yes">
|
||||
<source>Attribution</source>
|
||||
<target>Attribuzione</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer.homepage" xml:space="preserve" approved="yes">
|
||||
<source>Homepage</source>
|
||||
<target>Homepage</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_marker" xml:space="preserve" approved="yes">
|
||||
<source>Marker</source>
|
||||
<target>Segnaposto</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_marker.title" xml:space="preserve" approved="yes">
|
||||
<source>Title</source>
|
||||
<target>Titolo</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_marker.icon" xml:space="preserve" approved="yes">
|
||||
<source>Icon</source>
|
||||
<target>Icona</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_marker.size_x" xml:space="preserve" approved="yes">
|
||||
<source>Size X</source>
|
||||
<target>Dimensione X</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_marker.size_y" xml:space="preserve" approved="yes">
|
||||
<source>Size Y</source>
|
||||
<target>Dimensione Y</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_marker.offset_x" xml:space="preserve" approved="yes">
|
||||
<source>Offset X</source>
|
||||
<target>Offset X</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_marker.offset_y" xml:space="preserve" approved="yes">
|
||||
<source>Offset Y</source>
|
||||
<target>Offset Y</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_track" xml:space="preserve" approved="yes">
|
||||
<source>Track</source>
|
||||
<target>Percorso</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_track.title" xml:space="preserve" approved="yes">
|
||||
<source>Title</source>
|
||||
<target>Titolo</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_track.color" xml:space="preserve" approved="yes">
|
||||
<source>Color</source>
|
||||
<target>Colore</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_track.width" xml:space="preserve" approved="yes">
|
||||
<source>Width</source>
|
||||
<target>Larghezza</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_track.file" xml:space="preserve" approved="yes">
|
||||
<source>File</source>
|
||||
<target>File</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_track.min_lon" xml:space="preserve" approved="yes">
|
||||
<source>Minumum Longitude</source>
|
||||
<target>Longitudine minima</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_track.min_lat" xml:space="preserve" approved="yes">
|
||||
<source>Minimum Latitude</source>
|
||||
<target>Latitudine minima</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_track.max_lon" xml:space="preserve" approved="yes">
|
||||
<source>Maximum Longitude</source>
|
||||
<target>Longitudine massima</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_track.max_lat" xml:space="preserve" approved="yes">
|
||||
<source>Maximum Latitude</source>
|
||||
<target>Latitudine massima</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_vector" xml:space="preserve" approved="yes">
|
||||
<source>Vector</source>
|
||||
<target>Vettore</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_vector.title" xml:space="preserve" approved="yes">
|
||||
<source>Title</source>
|
||||
<target>Titolo</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_vector.data" xml:space="preserve" approved="yes">
|
||||
<source>GeoJSON</source>
|
||||
<target>GeoJSON</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_vector.file" xml:space="preserve" approved="yes">
|
||||
<source>File</source>
|
||||
<target></target>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<file source-language="en" datatype="plaintext" original="messages" date="2021-03-19T20:06:58Z" product-name="ods_osm">
|
||||
<header/>
|
||||
<body>
|
||||
<trans-unit id="pi1_title" xml:space="preserve">
|
||||
<source>OpenStreetMap</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="pi1_plus_wiz_description" xml:space="preserve">
|
||||
<source>Add an interactive map to your website.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="wiz_geocode" xml:space="preserve">
|
||||
<source>Geocode addresses</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="openlayers.showLayerList" xml:space="preserve">
|
||||
<source>Show layer list</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="openlayers.hideLayerList" xml:space="preserve">
|
||||
<source>Hide layer list</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="openlayers.clusterLayer" xml:space="preserve">
|
||||
<source>Cluster Layer</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="base_layer" xml:space="preserve">
|
||||
<source>Base Layer</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="overlays" xml:space="preserve">
|
||||
<source>Overlays</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="file" xml:space="preserve">
|
||||
<source>File</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="mouse_position" xml:space="preserve">
|
||||
<source>Mouse position</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
@@ -0,0 +1,281 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<file source-language="en" datatype="plaintext" original="messages" date="2021-03-19T20:06:52Z" product-name="ods_osm">
|
||||
<header/>
|
||||
<body>
|
||||
<trans-unit id="coordinatepickerWizard" xml:space="preserve">
|
||||
<source>Coordinate Picker Wizard</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="coordinatepickerWizard.title" xml:space="preserve">
|
||||
<source>Search coordinates</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="coordinatepickerWizard.close" xml:space="preserve">
|
||||
<source>Close Coordinate Picker Wizard</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="coordinatepickerWizard.import" xml:space="preserve">
|
||||
<source>Import Marker Coordinates</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="vectordrawWizard" xml:space="preserve">
|
||||
<source>Vector Draw Wizard</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="vectordrawWizard.title" xml:space="preserve">
|
||||
<source>Draw vector data and save as GeoJSON</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="vectordrawWizard.close">
|
||||
<source>Close Vector Draw Wizard</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="vectordrawWizard.import">
|
||||
<source>Import vector data to form</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_address_group.tx_odsosm_marker" xml:space="preserve">
|
||||
<source>Marker</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.list_type_pi1" xml:space="preserve">
|
||||
<source>OpenStreetMap</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.sheet_sDEF" xml:space="preserve">
|
||||
<source>Default</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.cluster" xml:space="preserve">
|
||||
<source>Cluster markers</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.cluster_radius" xml:space="preserve">
|
||||
<source>Cluster radius</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.marker" xml:space="preserve">
|
||||
<source>Records to show</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.marker.description" xml:space="preserve">
|
||||
<source>Select marker, track or vector records to show on the map.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.marker_popup_intial" xml:space="preserve">
|
||||
<source>Show this marker's popup initially</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.width" xml:space="preserve">
|
||||
<source>Width</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.height" xml:space="preserve">
|
||||
<source>Height</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.layer" xml:space="preserve">
|
||||
<source>Base layer</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.overlays_active" xml:space="preserve">
|
||||
<source>Activated overlays</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.overlays.description" xml:space="preserve">
|
||||
<source>The following overlays are available in the frontend.
|
||||
If using the layer switcher, the selected overlays may be toggled on/off. The initial state is selected by "overlays_active".
|
||||
Without layer switcher, all overlays are active in the map.
|
||||
</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.overlays_active.description" xml:space="preserve">
|
||||
<source>The following overlays are activated in the layer switcher initially.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.library" xml:space="preserve">
|
||||
<source>Library</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.position_show" xml:space="preserve">
|
||||
<source>Show current position</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.mouse_position" xml:space="preserve">
|
||||
<source>Show mouse position</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.show_popups" xml:space="preserve">
|
||||
<source>Show popups</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.show_popups.I.0" xml:space="preserve">
|
||||
<source>No</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.show_popups.I.1" xml:space="preserve">
|
||||
<source>Click</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.show_popups.I.2" xml:space="preserve">
|
||||
<source>Hover</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.show_layerswitcher" xml:space="preserve">
|
||||
<source>Show layerswitcher</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.show_layerswitcher.I.0" xml:space="preserve">
|
||||
<source>No</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.show_layerswitcher.I.1" xml:space="preserve">
|
||||
<source>Closed</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.show_layerswitcher.I.2" xml:space="preserve">
|
||||
<source>Opened</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.layerswitcher_activationMode" xml:space="preserve">
|
||||
<source>Layerswitcher Activation Mode</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.show_scalebar" xml:space="preserve">
|
||||
<source>Show ScaleBar</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.show_fullscreen" xml:space="preserve">
|
||||
<source>Show Fullscreen Button</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.use_coords_only_nomarker" xml:space="preserve">
|
||||
<source>Use this coordinates only if no marker exists</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.zoom" xml:space="preserve">
|
||||
<source>Zoom</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.enable_dragging" xml:space="preserve">
|
||||
<source>Enable dragging with mouse and touch</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tt_content.pi_flexform.enable_scrollwheelzoom" xml:space="preserve">
|
||||
<source>Enable zooming with mouse scroll wheel</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_lon" xml:space="preserve">
|
||||
<source>Longitude</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_lat" xml:space="preserve">
|
||||
<source>Latitude</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_geocache" xml:space="preserve">
|
||||
<source>Geocache</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_geocache.country" xml:space="preserve">
|
||||
<source>Country</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_geocache.state" xml:space="preserve">
|
||||
<source>State</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_geocache.city" xml:space="preserve">
|
||||
<source>City</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_geocache.zip" xml:space="preserve">
|
||||
<source>Zip</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_geocache.street" xml:space="preserve">
|
||||
<source>Street</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_geocache.housenumber" xml:space="preserve">
|
||||
<source>Housenumber</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_geocache.lon" xml:space="preserve">
|
||||
<source>Longitude</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_geocache.lat" xml:space="preserve">
|
||||
<source>Latitude</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_geocache.cache_hit" xml:space="preserve">
|
||||
<source>Hit from cache</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_geocache.service_hit" xml:space="preserve">
|
||||
<source>Hit from location service</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer" xml:space="preserve">
|
||||
<source>Layer</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer.title" xml:space="preserve">
|
||||
<source>Title</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer.overlay" xml:space="preserve">
|
||||
<source>Is overlay</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer.javascript_include" xml:space="preserve">
|
||||
<source>Include static JavaScript</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer.javascript_openlayers" xml:space="preserve">
|
||||
<source>JavaScript for OpenLayers</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer.static_url" xml:space="preserve">
|
||||
<source>Static map URL</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer.tile_url" xml:space="preserve">
|
||||
<source>Tile URL</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer.tile_https" xml:space="preserve">
|
||||
<source>Tile URL https available</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer.min_zoom" xml:space="preserve">
|
||||
<source>Minimum zoom</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer.max_zoom" xml:space="preserve">
|
||||
<source>Maximum zoom</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer.subdomains" xml:space="preserve">
|
||||
<source>Subdomains</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer.attribution" xml:space="preserve">
|
||||
<source>Attribution</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_layer.homepage" xml:space="preserve">
|
||||
<source>Homepage</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_marker" xml:space="preserve">
|
||||
<source>Marker</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_marker.title" xml:space="preserve">
|
||||
<source>Title</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_marker.icon" xml:space="preserve">
|
||||
<source>Icon</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_marker.size_x" xml:space="preserve">
|
||||
<source>Size X</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_marker.size_y" xml:space="preserve">
|
||||
<source>Size Y</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_marker.offset_x" xml:space="preserve">
|
||||
<source>Offset X</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_marker.offset_y" xml:space="preserve">
|
||||
<source>Offset Y</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_track" xml:space="preserve">
|
||||
<source>Track</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_track.title" xml:space="preserve">
|
||||
<source>Title</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_track.color" xml:space="preserve">
|
||||
<source>Color</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_track.width" xml:space="preserve">
|
||||
<source>Width</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_track.file" xml:space="preserve">
|
||||
<source>File</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_track.file.add" xml:space="preserve">
|
||||
<source>Add track file</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_track.min_lon" xml:space="preserve">
|
||||
<source>Minumum Longitude</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_track.min_lat" xml:space="preserve">
|
||||
<source>Minimum Latitude</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_track.max_lon" xml:space="preserve">
|
||||
<source>Maximum Longitude</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_track.max_lat" xml:space="preserve">
|
||||
<source>Maximum Latitude</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_vector" xml:space="preserve">
|
||||
<source>Vector</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_vector.title" xml:space="preserve">
|
||||
<source>Title</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_vector.data" xml:space="preserve">
|
||||
<source>GeoJSON</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_vector.file" xml:space="preserve">
|
||||
<source>File</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_vector.file.add" xml:space="preserve">
|
||||
<source>Add geo data file</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_vector.properties_from_file" xml:space="preserve">
|
||||
<source>Read properties from file</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="tx_odsosm_vector.properties" xml:space="preserve">
|
||||
<source>Properties to show in popup</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
BIN
typo3conf/ext/ods_osm/Resources/Private/geophp.phar
Normal file
@@ -0,0 +1,39 @@
|
||||
#t3js-location-map-wrap {
|
||||
position: absolute;
|
||||
width: 80vw;
|
||||
height: 80vh;
|
||||
top: 6vh;
|
||||
left: 10vw;
|
||||
opacity: 0;
|
||||
box-shadow: 0 2px 15px #000;
|
||||
transition: opacity 1500ms;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
#t3js-location-map-wrap.active {
|
||||
opacity: 1;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.t3js-location-map-container {
|
||||
width: 100%;
|
||||
height: calc(100% - 40px);
|
||||
border: 1px solid #CCC;
|
||||
}
|
||||
|
||||
.t3js-location-map-title>div.btn-group {
|
||||
position: absolute;
|
||||
left: 15px;
|
||||
}
|
||||
|
||||
.t3js-location-map-title a {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.t3js-location-map-title {
|
||||
background: rgb(237, 237, 237);
|
||||
font-family: Share, Verdana, Arial, Helvetica, sans-serif;
|
||||
font-size: 20px;
|
||||
padding: 5px 15px;
|
||||
text-align: center;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#t3js-location-map-wrap {
|
||||
position: absolute;
|
||||
width: 80vw;
|
||||
height: 80vh;
|
||||
top: 6vh;
|
||||
left: 10vw;
|
||||
opacity: 0;
|
||||
box-shadow: 0 2px 15px #000;
|
||||
transition: opacity 1500ms;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
#t3js-location-map-wrap.active {
|
||||
opacity: 1;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.t3js-location-map-container {
|
||||
width: 100%;
|
||||
height: calc(100% - 40px);
|
||||
border: 1px solid #CCC;
|
||||
}
|
||||
|
||||
.t3js-location-map-title>div.btn-group {
|
||||
position: absolute;
|
||||
left: 15px;
|
||||
}
|
||||
|
||||
.t3js-location-map-title a {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.t3js-location-map-title {
|
||||
background: rgb(237, 237, 237);
|
||||
font-family: Share, Verdana, Arial, Helvetica, sans-serif;
|
||||
font-size: 20px;
|
||||
padding: 5px 15px;
|
||||
text-align: center;
|
||||
}
|
||||
65
typo3conf/ext/ods_osm/Resources/Public/Css/ods_osm.css
Normal file
@@ -0,0 +1,65 @@
|
||||
.ol-control button,
|
||||
.ol-attribution,
|
||||
.ol-scale-line-inner {
|
||||
font-family: 'Lucida Grande', Verdana, Geneva, Lucida, Arial, Helvetica, sans-serif !important;
|
||||
}
|
||||
|
||||
.ol-popup {
|
||||
font-family: 'Lucida Grande', Verdana, Geneva, Lucida, Arial, Helvetica, sans-serif !important;
|
||||
font-size: 12px;
|
||||
position: absolute;
|
||||
background-color: white;
|
||||
-webkit-filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2));
|
||||
filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2));
|
||||
padding: 10px;
|
||||
border-radius: 10px;
|
||||
border: 1px solid #cccccc;
|
||||
bottom: 12px;
|
||||
left: -50px;
|
||||
min-width: 100px;
|
||||
}
|
||||
|
||||
.ol-popup dl {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.ol-popup:after,
|
||||
.ol-popup:before {
|
||||
top: 100%;
|
||||
border: solid transparent;
|
||||
content: " ";
|
||||
height: 0;
|
||||
width: 0;
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.ol-popup:after {
|
||||
border-top-color: white;
|
||||
border-width: 10px;
|
||||
left: 48px;
|
||||
margin-left: -10px;
|
||||
}
|
||||
|
||||
.ol-popup:before {
|
||||
border-top-color: #cccccc;
|
||||
border-width: 11px;
|
||||
left: 48px;
|
||||
margin-left: -11px;
|
||||
}
|
||||
|
||||
.ol-popup-closer {
|
||||
text-decoration: none;
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
right: 8px;
|
||||
}
|
||||
|
||||
.ol-popup-closer:after {
|
||||
content: "✖";
|
||||
color: #c3c3c3;
|
||||
}
|
||||
|
||||
img.marker-icon {
|
||||
max-height: 45px;
|
||||
}
|
||||
BIN
typo3conf/ext/ods_osm/Resources/Public/Icons/Extension.gif
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
typo3conf/ext/ods_osm/Resources/Public/Icons/ce_wiz.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 290 B |
|
After Width: | Height: | Size: 566 B |
|
After Width: | Height: | Size: 418 B |
|
After Width: | Height: | Size: 894 B |
|
After Width: | Height: | Size: 424 B |
BIN
typo3conf/ext/ods_osm/Resources/Public/Icons/marker-icon.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
typo3conf/ext/ods_osm/Resources/Public/Icons/osm.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
typo3conf/ext/ods_osm/Resources/Public/Icons/vector.png
Normal file
|
After Width: | Height: | Size: 712 B |
@@ -0,0 +1,194 @@
|
||||
define(['jquery', 'TYPO3/CMS/Backend/Icons', 'TYPO3/CMS/Backend/FormEngine', 'TYPO3/CMS/OdsOsm/Leaflet/Core/leaflet'], function ($, Icons, FormEngine) {
|
||||
'use strict';
|
||||
|
||||
let LeafBE = {
|
||||
$element: null,
|
||||
$gLatitude: null,
|
||||
$gLongitude: null,
|
||||
$latitude: null,
|
||||
$longitude: null,
|
||||
$fieldLat: null,
|
||||
$fieldLon: null,
|
||||
$fieldLatActive: null,
|
||||
$geoCodeUrl: null,
|
||||
$geoCodeUrlShort: null,
|
||||
$tilesUrl: null,
|
||||
$tilesCopy: null,
|
||||
$zoomLevel: 7,
|
||||
$marker: null,
|
||||
$map: null,
|
||||
$iconClose: null
|
||||
};
|
||||
|
||||
// Load icon via TYPO3 Icon-API and requireJS
|
||||
Icons.getIcon('actions-close', Icons.sizes.small, null, null).then(function(markup) {
|
||||
LeafBE['$iconClose']= markup;
|
||||
});
|
||||
|
||||
LeafBE.init = function (element) {
|
||||
// basic variable initialisation, uses data vars on the trigger button
|
||||
LeafBE.$element = element;
|
||||
LeafBE.$labelTitle = LeafBE.$element.attr('data-label-title');
|
||||
LeafBE.$labelClose = LeafBE.$element.attr('data-label-close');
|
||||
LeafBE.$labelImport = LeafBE.$element.attr('data-label-import');
|
||||
LeafBE.$latitude = LeafBE.$element.attr('data-lat');
|
||||
LeafBE.$longitude = LeafBE.$element.attr('data-lon');
|
||||
LeafBE.$gLatitude = LeafBE.$element.attr('data-default-lat');
|
||||
LeafBE.$gLongitude = LeafBE.$element.attr('data-default-lon');
|
||||
LeafBE.$zoomLevel = LeafBE.$element.attr('data-default-zoom');
|
||||
LeafBE.$tilesUrl = LeafBE.$element.attr('data-tiles');
|
||||
LeafBE.$tilesCopy = LeafBE.$element.attr('data-copy');
|
||||
LeafBE.$geoCodeUrl = LeafBE.$element.attr('data-geocodeurl');
|
||||
LeafBE.$geoCodeUrlShort = LeafBE.$element.attr('data-geocodeurlshort');
|
||||
LeafBE.$fieldLat = LeafBE.$element.attr('data-namelat');
|
||||
LeafBE.$fieldLon = LeafBE.$element.attr('data-namelon');
|
||||
LeafBE.$fieldLatActive = LeafBE.$element.attr('data-namelat-active');
|
||||
|
||||
// add the container to display the map as a nice overlay
|
||||
if (!$('#t3js-location-map-wrap').length) {
|
||||
LeafBE.addMapMarkup();
|
||||
}
|
||||
};
|
||||
|
||||
LeafBE.addMapMarkup = function () {
|
||||
$('body').append(
|
||||
'<div id="t3js-location-map-wrap">' +
|
||||
'<div class="t3js-location-map-title">' +
|
||||
'<div class="btn-group"><a href="#" class="btn btn-icon btn-default" title="' + LeafBE.$labelClose + '" id="t3js-ttaddress-close-map">' +
|
||||
LeafBE.$iconClose +
|
||||
'</a>' +
|
||||
'<a class="btn btn-default" href="#" title="' + LeafBE.$labelImport + '" id="t3js-ttaddress-import-position">' +
|
||||
LeafBE.$labelImport +
|
||||
'</a></div>' +
|
||||
LeafBE.$labelTitle +
|
||||
'</div>' +
|
||||
'<div class="t3js-location-map-container" id="t3js-location-map-container">' +
|
||||
'</div>' +
|
||||
'</div>'
|
||||
);
|
||||
};
|
||||
|
||||
LeafBE.createMap = function () {
|
||||
|
||||
if (((!LeafBE.$latitude || !LeafBE.$longitude) || (LeafBE.$latitude == 0 && LeafBE.$longitude == 0)) && LeafBE.$geoCodeUrl != null) {
|
||||
LeafBE.geocode();
|
||||
}
|
||||
|
||||
// If one of the coordinates is empty, fallback to default values set in extension configuration.
|
||||
if (LeafBE.$latitude == null || LeafBE.$longitude == null || (LeafBE.$latitude == 0 && LeafBE.$longitude == 0)) {
|
||||
LeafBE.$latitude = LeafBE.$gLatitude;
|
||||
LeafBE.$longitude = LeafBE.$gLongitude;
|
||||
}
|
||||
|
||||
LeafBE.$map = L.map('t3js-location-map-container', {
|
||||
center: [LeafBE.$latitude, LeafBE.$longitude],
|
||||
zoom: LeafBE.$zoomLevel
|
||||
});
|
||||
L.tileLayer(LeafBE.$tilesUrl, {
|
||||
attribution: LeafBE.$tilesCopy
|
||||
}).addTo(LeafBE.$map);
|
||||
|
||||
LeafBE.$marker = L.marker([LeafBE.$latitude, LeafBE.$longitude], {
|
||||
draggable: true
|
||||
}).addTo(LeafBE.$map);
|
||||
|
||||
let position = LeafBE.$marker.getLatLng();
|
||||
|
||||
LeafBE.$marker.on('dragend', function (event) {
|
||||
LeafBE.$marker = event.target;
|
||||
position = LeafBE.$marker.getLatLng();
|
||||
});
|
||||
LeafBE.$map.on('click', function (event) {
|
||||
LeafBE.$marker.setLatLng(event.latlng);
|
||||
});
|
||||
// import coordinates and close overlay
|
||||
$('#t3js-ttaddress-import-position').on('click', function () {
|
||||
// set visual coordinates
|
||||
$('input[data-formengine-input-name="' + LeafBE.$fieldLat + '"]').val(LeafBE.$marker.getLatLng().lat);
|
||||
$('input[data-formengine-input-name="' + LeafBE.$fieldLon + '"]').val(LeafBE.$marker.getLatLng().lng);
|
||||
// set hidden fields values
|
||||
$('input[name="' + LeafBE.$fieldLat + '"]').val(LeafBE.$marker.getLatLng().lat);
|
||||
$('input[name="' + LeafBE.$fieldLon + '"]').val(LeafBE.$marker.getLatLng().lng);
|
||||
// enable also latitude, if not already done by user.
|
||||
$('input[id="' + LeafBE.$fieldLatActive + '"]').parentsUntil('.form-group').removeClass('disabled');
|
||||
$('input[id="' + LeafBE.$fieldLatActive + '"]').prop('checked', true);
|
||||
|
||||
// mark fields as changed for re-evaluation and revalidate the form,
|
||||
// this is e.g. needed when this wizard is used on inline elements
|
||||
FormEngine.Validation.markFieldAsChanged($('input[name="' + LeafBE.$fieldLat + '"]'));
|
||||
FormEngine.Validation.markFieldAsChanged($('input[name="' + LeafBE.$fieldLon + '"]'));
|
||||
FormEngine.Validation.validate();
|
||||
|
||||
// close map after import of coordinates.
|
||||
$('#t3js-location-map-wrap').removeClass('active');
|
||||
});
|
||||
// close overlay without any further action
|
||||
$('#t3js-ttaddress-close-map').on('click', function () {
|
||||
$('#t3js-location-map-wrap').removeClass('active');
|
||||
});
|
||||
};
|
||||
|
||||
LeafBE.geocode = function () {
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
url: LeafBE.$geoCodeUrl,
|
||||
async: false,
|
||||
dataType: 'json',
|
||||
success: function (data) {
|
||||
if (data.length == 0) {
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
url: LeafBE.$geoCodeUrlShort,
|
||||
async: false,
|
||||
dataType: 'json',
|
||||
success: function (data) {
|
||||
if (data.length != 0) {
|
||||
$.each(data[0], function (key, value) {
|
||||
if (key == "lat") {
|
||||
LeafBE.$latitude = value;
|
||||
}
|
||||
if (key == "lon") {
|
||||
LeafBE.$longitude = value;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$.each(data[0], function (key, value) {
|
||||
if (key == "lat") {
|
||||
LeafBE.$latitude = value;
|
||||
}
|
||||
if (key == "lon") {
|
||||
LeafBE.$longitude = value;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
LeafBE.initializeEvents = function (element) {
|
||||
$(element).on('click', function () {
|
||||
if (LeafBE.$map !== null) {
|
||||
LeafBE.$map.remove();
|
||||
LeafBE.$map = null;
|
||||
}
|
||||
LeafBE.init($(this));
|
||||
LeafBE.createMap();
|
||||
$('#t3js-location-map-wrap').addClass('active');
|
||||
});
|
||||
};
|
||||
|
||||
// reinit when form has changes, e.g. inline relations loaded using ajax
|
||||
LeafBE.reinitialize = FormEngine.reinitialize;
|
||||
FormEngine.reinitialize = function () {
|
||||
LeafBE.reinitialize();
|
||||
if ($('.coordinatepickerWizard').length) {
|
||||
LeafBE.initializeEvents('.coordinatepickerWizard');
|
||||
}
|
||||
};
|
||||
//LeafBE.addMapMarkup();
|
||||
LeafBE.initializeEvents('.coordinatepickerWizard');
|
||||
return LeafBE;
|
||||
});
|
||||
@@ -0,0 +1,202 @@
|
||||
define(['jquery', 'TYPO3/CMS/Backend/Icons', 'TYPO3/CMS/Backend/FormEngine', 'TYPO3/CMS/OdsOsm/Leaflet/Core/leaflet', 'TYPO3/CMS/OdsOsm/Leaflet/leaflet-draw/leaflet.draw'], function ($, Icons, FormEngine) {
|
||||
'use strict';
|
||||
|
||||
let LeafBE = {
|
||||
$element: null,
|
||||
$min_lat: null,
|
||||
$max_lat: null,
|
||||
$min_lon: null,
|
||||
$max_lon: null,
|
||||
$latitude: null,
|
||||
$longitude: null,
|
||||
$fieldData: null,
|
||||
$fieldLat: null,
|
||||
$fieldLon: null,
|
||||
$tilesUrl: null,
|
||||
$tilesCopy: null,
|
||||
$zoomLevel: 7,
|
||||
$map: null,
|
||||
$iconClose: null,
|
||||
$drawnItems: null,
|
||||
$drawControl: null
|
||||
};
|
||||
|
||||
// Load icon via TYPO3 Icon-API and requireJS
|
||||
Icons.getIcon('actions-close', Icons.sizes.small, null, null).then(function(markup) {
|
||||
LeafBE['$iconClose']= markup;
|
||||
});
|
||||
|
||||
LeafBE.init = function (element) {
|
||||
// basic variable initialisation, uses data vars on the trigger button
|
||||
LeafBE.$element = element;
|
||||
LeafBE.$labelTitle = LeafBE.$element.attr('data-label-title');
|
||||
LeafBE.$labelClose = LeafBE.$element.attr('data-label-close');
|
||||
LeafBE.$labelImport = LeafBE.$element.attr('data-label-import');
|
||||
LeafBE.$min_lon = LeafBE.$element.attr('data-minlon');
|
||||
LeafBE.$max_lon = LeafBE.$element.attr('data-maxlon');
|
||||
LeafBE.$min_lat = LeafBE.$element.attr('data-minlat');
|
||||
LeafBE.$max_lat = LeafBE.$element.attr('data-maxlat');
|
||||
LeafBE.$latitude = LeafBE.$element.attr('data-lat');
|
||||
LeafBE.$longitude = LeafBE.$element.attr('data-lon');
|
||||
LeafBE.$tilesUrl = LeafBE.$element.attr('data-tiles');
|
||||
LeafBE.$tilesCopy = LeafBE.$element.attr('data-copy');
|
||||
LeafBE.$fieldLat = LeafBE.$element.attr('data-namelat');
|
||||
LeafBE.$fieldLon = LeafBE.$element.attr('data-namelon');
|
||||
LeafBE.$fieldDataName = LeafBE.$element.attr('data-fieldName');
|
||||
LeafBE.$fieldDataValue = LeafBE.$element.attr('data-fieldValue');
|
||||
|
||||
// add the container to display the map as a nice overlay
|
||||
if (!$('#t3js-location-map-wrap').length) {
|
||||
LeafBE.addMapMarkup();
|
||||
}
|
||||
};
|
||||
|
||||
LeafBE.addMapMarkup = function () {
|
||||
$('body').append(
|
||||
'<div id="t3js-location-map-wrap">' +
|
||||
'<div class="t3js-location-map-title">' +
|
||||
'<div class="btn-group"><a href="#" class="btn btn-icon btn-default" title="' + LeafBE.$labelClose + '" id="t3js-ttaddress-close-map">' +
|
||||
LeafBE.$iconClose +
|
||||
'</a>' +
|
||||
'<a class="btn btn-default" href="#" title="' + LeafBE.$labelImport + '" id="t3js-ttaddress-import-position">' +
|
||||
LeafBE.$labelImport +
|
||||
'</a></div>' +
|
||||
LeafBE.$labelTitle +
|
||||
'</div>' +
|
||||
'<div class="t3js-location-map-container" id="t3js-location-map-container">' +
|
||||
'</div>' +
|
||||
'</div>'
|
||||
);
|
||||
};
|
||||
|
||||
LeafBE.createMap = function () {
|
||||
|
||||
// set to center point with default zoom level
|
||||
LeafBE.$map = L.map('t3js-location-map-container', {
|
||||
center: [LeafBE.$latitude, LeafBE.$longitude],
|
||||
zoom: LeafBE.$zoomLevel
|
||||
});
|
||||
|
||||
if (LeafBE.$min_lat && LeafBE.$min_lon && LeafBE.$max_lat && LeafBE.$max_lon) {
|
||||
// if bounds are given, fit to it
|
||||
LeafBE.$map.fitBounds([
|
||||
[LeafBE.$min_lat, LeafBE.$min_lon],
|
||||
[LeafBE.$max_lat, LeafBE.$max_lon]
|
||||
]);
|
||||
}
|
||||
|
||||
L.tileLayer(LeafBE.$tilesUrl, {
|
||||
attribution: LeafBE.$tilesCopy
|
||||
}).addTo(LeafBE.$map);
|
||||
|
||||
var drawnItems = new L.FeatureGroup().addTo(LeafBE.$map);
|
||||
|
||||
L.control.layers({}, {'GeoJSON Data':drawnItems}, { position: 'topright', collapsed: false }).addTo(LeafBE.$map);
|
||||
|
||||
LeafBE.$map.addControl(new L.Control.Draw({
|
||||
edit: {
|
||||
featureGroup: drawnItems,
|
||||
poly: {
|
||||
allowIntersection: false
|
||||
}
|
||||
},
|
||||
draw: {
|
||||
polygon: {
|
||||
allowIntersection: false,
|
||||
showArea: true
|
||||
},
|
||||
circle: false,
|
||||
circlemarker: false
|
||||
}
|
||||
}));
|
||||
|
||||
if (LeafBE.$fieldDataValue) {
|
||||
// convert data from data field to JavaScript object
|
||||
var myGeoJson = JSON.parse(LeafBE.$fieldDataValue.toString());
|
||||
|
||||
var geoJsonGroup = L.geoJSON(myGeoJson);
|
||||
|
||||
// add feature by feature to drawnItems layer
|
||||
addNonGroupLayers(geoJsonGroup, drawnItems);
|
||||
|
||||
// Would benefit from https://github.com/Leaflet/Leaflet/issues/4461
|
||||
function addNonGroupLayers(sourceLayer, targetGroup) {
|
||||
if (sourceLayer instanceof L.LayerGroup) {
|
||||
sourceLayer.eachLayer(function (layer) {
|
||||
addNonGroupLayers(layer, targetGroup);
|
||||
});
|
||||
} else {
|
||||
targetGroup.addLayer(sourceLayer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Object created - add to feature group
|
||||
LeafBE.$map.on(L.Draw.Event.CREATED, function(event) {
|
||||
var layer = event.layer;
|
||||
drawnItems.addLayer(layer);
|
||||
});
|
||||
|
||||
// Object(s) edited - update popups
|
||||
LeafBE.$map.on(L.Draw.Event.EDITED, function(event) {
|
||||
var layers = event.layers,
|
||||
content = null;
|
||||
layers.eachLayer(function(layer) {
|
||||
content = getPopupContent(layer);
|
||||
if (content !== null) {
|
||||
layer.setPopupContent(content);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// import drawn vector data and close overlay
|
||||
$('#t3js-ttaddress-import-position').on('click', function () {
|
||||
|
||||
// Extract GeoJson from featureGroup
|
||||
var data = drawnItems.toGeoJSON();
|
||||
|
||||
// Stringify the GeoJson
|
||||
var convertedData = JSON.stringify(data);
|
||||
|
||||
// fill form textarea with new GeoJSON-data
|
||||
$('textarea[data-formengine-input-name="' + LeafBE.$fieldDataName + '"]').val(convertedData);
|
||||
|
||||
// mark fields as changed for re-evaluation and revalidate the form,
|
||||
// this is e.g. needed when this wizard is used on inline elements
|
||||
FormEngine.Validation.markFieldAsChanged($('input[name="' + LeafBE.$fieldDataName + '"]'));
|
||||
FormEngine.Validation.validate();
|
||||
|
||||
// close map after import of coordinates.
|
||||
$('#t3js-location-map-wrap').removeClass('active');
|
||||
});
|
||||
// close overlay without any further action
|
||||
$('#t3js-ttaddress-close-map').on('click', function () {
|
||||
$('#t3js-location-map-wrap').removeClass('active');
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
LeafBE.initializeEvents = function (element) {
|
||||
$(element).on('click', function () {
|
||||
if (LeafBE.$map !== null) {
|
||||
LeafBE.$map.remove();
|
||||
LeafBE.$map = null;
|
||||
}
|
||||
LeafBE.init($(this));
|
||||
LeafBE.createMap();
|
||||
$('#t3js-location-map-wrap').addClass('active');
|
||||
});
|
||||
};
|
||||
|
||||
// reinit when form has changes, e.g. inline relations loaded using ajax
|
||||
LeafBE.reinitialize = FormEngine.reinitialize;
|
||||
FormEngine.reinitialize = function () {
|
||||
LeafBE.reinitialize();
|
||||
if ($('.vectordrawWizard').length) {
|
||||
LeafBE.initializeEvents('.vectordrawWizard');
|
||||
}
|
||||
};
|
||||
//LeafBE.addMapMarkup();
|
||||
LeafBE.initializeEvents('.vectordrawWizard');
|
||||
return LeafBE;
|
||||
});
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 696 B |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 618 B |
@@ -0,0 +1,661 @@
|
||||
/* required styles */
|
||||
|
||||
.leaflet-pane,
|
||||
.leaflet-tile,
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow,
|
||||
.leaflet-tile-container,
|
||||
.leaflet-pane > svg,
|
||||
.leaflet-pane > canvas,
|
||||
.leaflet-zoom-box,
|
||||
.leaflet-image-layer,
|
||||
.leaflet-layer {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
.leaflet-container {
|
||||
overflow: hidden;
|
||||
}
|
||||
.leaflet-tile,
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow {
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
-webkit-user-drag: none;
|
||||
}
|
||||
/* Prevents IE11 from highlighting tiles in blue */
|
||||
.leaflet-tile::selection {
|
||||
background: transparent;
|
||||
}
|
||||
/* Safari renders non-retina tile on retina better with this, but Chrome is worse */
|
||||
.leaflet-safari .leaflet-tile {
|
||||
image-rendering: -webkit-optimize-contrast;
|
||||
}
|
||||
/* hack that prevents hw layers "stretching" when loading new tiles */
|
||||
.leaflet-safari .leaflet-tile-container {
|
||||
width: 1600px;
|
||||
height: 1600px;
|
||||
-webkit-transform-origin: 0 0;
|
||||
}
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow {
|
||||
display: block;
|
||||
}
|
||||
/* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */
|
||||
/* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */
|
||||
.leaflet-container .leaflet-overlay-pane svg {
|
||||
max-width: none !important;
|
||||
max-height: none !important;
|
||||
}
|
||||
.leaflet-container .leaflet-marker-pane img,
|
||||
.leaflet-container .leaflet-shadow-pane img,
|
||||
.leaflet-container .leaflet-tile-pane img,
|
||||
.leaflet-container img.leaflet-image-layer,
|
||||
.leaflet-container .leaflet-tile {
|
||||
max-width: none !important;
|
||||
max-height: none !important;
|
||||
width: auto;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.leaflet-container img.leaflet-tile {
|
||||
/* See: https://bugs.chromium.org/p/chromium/issues/detail?id=600120 */
|
||||
mix-blend-mode: plus-lighter;
|
||||
}
|
||||
|
||||
.leaflet-container.leaflet-touch-zoom {
|
||||
-ms-touch-action: pan-x pan-y;
|
||||
touch-action: pan-x pan-y;
|
||||
}
|
||||
.leaflet-container.leaflet-touch-drag {
|
||||
-ms-touch-action: pinch-zoom;
|
||||
/* Fallback for FF which doesn't support pinch-zoom */
|
||||
touch-action: none;
|
||||
touch-action: pinch-zoom;
|
||||
}
|
||||
.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom {
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
.leaflet-container {
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
.leaflet-container a {
|
||||
-webkit-tap-highlight-color: rgba(51, 181, 229, 0.4);
|
||||
}
|
||||
.leaflet-tile {
|
||||
filter: inherit;
|
||||
visibility: hidden;
|
||||
}
|
||||
.leaflet-tile-loaded {
|
||||
visibility: inherit;
|
||||
}
|
||||
.leaflet-zoom-box {
|
||||
width: 0;
|
||||
height: 0;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
z-index: 800;
|
||||
}
|
||||
/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */
|
||||
.leaflet-overlay-pane svg {
|
||||
-moz-user-select: none;
|
||||
}
|
||||
|
||||
.leaflet-pane { z-index: 400; }
|
||||
|
||||
.leaflet-tile-pane { z-index: 200; }
|
||||
.leaflet-overlay-pane { z-index: 400; }
|
||||
.leaflet-shadow-pane { z-index: 500; }
|
||||
.leaflet-marker-pane { z-index: 600; }
|
||||
.leaflet-tooltip-pane { z-index: 650; }
|
||||
.leaflet-popup-pane { z-index: 700; }
|
||||
|
||||
.leaflet-map-pane canvas { z-index: 100; }
|
||||
.leaflet-map-pane svg { z-index: 200; }
|
||||
|
||||
.leaflet-vml-shape {
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
}
|
||||
.lvml {
|
||||
behavior: url(#default#VML);
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
|
||||
/* control positioning */
|
||||
|
||||
.leaflet-control {
|
||||
position: relative;
|
||||
z-index: 800;
|
||||
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
|
||||
pointer-events: auto;
|
||||
}
|
||||
.leaflet-top,
|
||||
.leaflet-bottom {
|
||||
position: absolute;
|
||||
z-index: 1000;
|
||||
pointer-events: none;
|
||||
}
|
||||
.leaflet-top {
|
||||
top: 0;
|
||||
}
|
||||
.leaflet-right {
|
||||
right: 0;
|
||||
}
|
||||
.leaflet-bottom {
|
||||
bottom: 0;
|
||||
}
|
||||
.leaflet-left {
|
||||
left: 0;
|
||||
}
|
||||
.leaflet-control {
|
||||
float: left;
|
||||
clear: both;
|
||||
}
|
||||
.leaflet-right .leaflet-control {
|
||||
float: right;
|
||||
}
|
||||
.leaflet-top .leaflet-control {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.leaflet-bottom .leaflet-control {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.leaflet-left .leaflet-control {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.leaflet-right .leaflet-control {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
|
||||
/* zoom and fade animations */
|
||||
|
||||
.leaflet-fade-anim .leaflet-popup {
|
||||
opacity: 0;
|
||||
-webkit-transition: opacity 0.2s linear;
|
||||
-moz-transition: opacity 0.2s linear;
|
||||
transition: opacity 0.2s linear;
|
||||
}
|
||||
.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
|
||||
opacity: 1;
|
||||
}
|
||||
.leaflet-zoom-animated {
|
||||
-webkit-transform-origin: 0 0;
|
||||
-ms-transform-origin: 0 0;
|
||||
transform-origin: 0 0;
|
||||
}
|
||||
svg.leaflet-zoom-animated {
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
.leaflet-zoom-anim .leaflet-zoom-animated {
|
||||
-webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
-moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
transition: transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
}
|
||||
.leaflet-zoom-anim .leaflet-tile,
|
||||
.leaflet-pan-anim .leaflet-tile {
|
||||
-webkit-transition: none;
|
||||
-moz-transition: none;
|
||||
transition: none;
|
||||
}
|
||||
|
||||
.leaflet-zoom-anim .leaflet-zoom-hide {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
|
||||
/* cursors */
|
||||
|
||||
.leaflet-interactive {
|
||||
cursor: pointer;
|
||||
}
|
||||
.leaflet-grab {
|
||||
cursor: -webkit-grab;
|
||||
cursor: -moz-grab;
|
||||
cursor: grab;
|
||||
}
|
||||
.leaflet-crosshair,
|
||||
.leaflet-crosshair .leaflet-interactive {
|
||||
cursor: crosshair;
|
||||
}
|
||||
.leaflet-popup-pane,
|
||||
.leaflet-control {
|
||||
cursor: auto;
|
||||
}
|
||||
.leaflet-dragging .leaflet-grab,
|
||||
.leaflet-dragging .leaflet-grab .leaflet-interactive,
|
||||
.leaflet-dragging .leaflet-marker-draggable {
|
||||
cursor: move;
|
||||
cursor: -webkit-grabbing;
|
||||
cursor: -moz-grabbing;
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
/* marker & overlays interactivity */
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow,
|
||||
.leaflet-image-layer,
|
||||
.leaflet-pane > svg path,
|
||||
.leaflet-tile-container {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.leaflet-marker-icon.leaflet-interactive,
|
||||
.leaflet-image-layer.leaflet-interactive,
|
||||
.leaflet-pane > svg path.leaflet-interactive,
|
||||
svg.leaflet-image-layer.leaflet-interactive path {
|
||||
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
/* visual tweaks */
|
||||
|
||||
.leaflet-container {
|
||||
background: #ddd;
|
||||
outline-offset: 1px;
|
||||
}
|
||||
.leaflet-container a {
|
||||
color: #0078A8;
|
||||
}
|
||||
.leaflet-zoom-box {
|
||||
border: 2px dotted #38f;
|
||||
background: rgba(255,255,255,0.5);
|
||||
}
|
||||
|
||||
|
||||
/* general typography */
|
||||
.leaflet-container {
|
||||
font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;
|
||||
font-size: 12px;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
|
||||
/* general toolbar styles */
|
||||
|
||||
.leaflet-bar {
|
||||
box-shadow: 0 1px 5px rgba(0,0,0,0.65);
|
||||
border-radius: 4px;
|
||||
}
|
||||
.leaflet-bar a {
|
||||
background-color: #fff;
|
||||
border-bottom: 1px solid #ccc;
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
display: block;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
}
|
||||
.leaflet-bar a,
|
||||
.leaflet-control-layers-toggle {
|
||||
background-position: 50% 50%;
|
||||
background-repeat: no-repeat;
|
||||
display: block;
|
||||
}
|
||||
.leaflet-bar a:hover,
|
||||
.leaflet-bar a:focus {
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
.leaflet-bar a:first-child {
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
}
|
||||
.leaflet-bar a:last-child {
|
||||
border-bottom-left-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
border-bottom: none;
|
||||
}
|
||||
.leaflet-bar a.leaflet-disabled {
|
||||
cursor: default;
|
||||
background-color: #f4f4f4;
|
||||
color: #bbb;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-bar a {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
}
|
||||
.leaflet-touch .leaflet-bar a:first-child {
|
||||
border-top-left-radius: 2px;
|
||||
border-top-right-radius: 2px;
|
||||
}
|
||||
.leaflet-touch .leaflet-bar a:last-child {
|
||||
border-bottom-left-radius: 2px;
|
||||
border-bottom-right-radius: 2px;
|
||||
}
|
||||
|
||||
/* zoom control */
|
||||
|
||||
.leaflet-control-zoom-in,
|
||||
.leaflet-control-zoom-out {
|
||||
font: bold 18px 'Lucida Console', Monaco, monospace;
|
||||
text-indent: 1px;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-control-zoom-in, .leaflet-touch .leaflet-control-zoom-out {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
|
||||
/* layers control */
|
||||
|
||||
.leaflet-control-layers {
|
||||
box-shadow: 0 1px 5px rgba(0,0,0,0.4);
|
||||
background: #fff;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.leaflet-control-layers-toggle {
|
||||
background-image: url(images/layers.png);
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
}
|
||||
.leaflet-retina .leaflet-control-layers-toggle {
|
||||
background-image: url(images/layers-2x.png);
|
||||
background-size: 26px 26px;
|
||||
}
|
||||
.leaflet-touch .leaflet-control-layers-toggle {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
}
|
||||
.leaflet-control-layers .leaflet-control-layers-list,
|
||||
.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
|
||||
display: none;
|
||||
}
|
||||
.leaflet-control-layers-expanded .leaflet-control-layers-list {
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
.leaflet-control-layers-expanded {
|
||||
padding: 6px 10px 6px 6px;
|
||||
color: #333;
|
||||
background: #fff;
|
||||
}
|
||||
.leaflet-control-layers-scrollbar {
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
padding-right: 5px;
|
||||
}
|
||||
.leaflet-control-layers-selector {
|
||||
margin-top: 2px;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
.leaflet-control-layers label {
|
||||
display: block;
|
||||
font-size: 13px;
|
||||
font-size: 1.08333em;
|
||||
}
|
||||
.leaflet-control-layers-separator {
|
||||
height: 0;
|
||||
border-top: 1px solid #ddd;
|
||||
margin: 5px -10px 5px -6px;
|
||||
}
|
||||
|
||||
/* Default icon URLs */
|
||||
.leaflet-default-icon-path { /* used only in path-guessing heuristic, see L.Icon.Default */
|
||||
background-image: url(images/marker-icon.png);
|
||||
}
|
||||
|
||||
|
||||
/* attribution and scale controls */
|
||||
|
||||
.leaflet-container .leaflet-control-attribution {
|
||||
background: #fff;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
margin: 0;
|
||||
}
|
||||
.leaflet-control-attribution,
|
||||
.leaflet-control-scale-line {
|
||||
padding: 0 5px;
|
||||
color: #333;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.leaflet-control-attribution a {
|
||||
text-decoration: none;
|
||||
}
|
||||
.leaflet-control-attribution a:hover,
|
||||
.leaflet-control-attribution a:focus {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.leaflet-attribution-flag {
|
||||
display: inline !important;
|
||||
vertical-align: baseline !important;
|
||||
width: 1em;
|
||||
height: 0.6669em;
|
||||
}
|
||||
.leaflet-left .leaflet-control-scale {
|
||||
margin-left: 5px;
|
||||
}
|
||||
.leaflet-bottom .leaflet-control-scale {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.leaflet-control-scale-line {
|
||||
border: 2px solid #777;
|
||||
border-top: none;
|
||||
line-height: 1.1;
|
||||
padding: 2px 5px 1px;
|
||||
white-space: nowrap;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
text-shadow: 1px 1px #fff;
|
||||
}
|
||||
.leaflet-control-scale-line:not(:first-child) {
|
||||
border-top: 2px solid #777;
|
||||
border-bottom: none;
|
||||
margin-top: -2px;
|
||||
}
|
||||
.leaflet-control-scale-line:not(:first-child):not(:last-child) {
|
||||
border-bottom: 2px solid #777;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-control-attribution,
|
||||
.leaflet-touch .leaflet-control-layers,
|
||||
.leaflet-touch .leaflet-bar {
|
||||
box-shadow: none;
|
||||
}
|
||||
.leaflet-touch .leaflet-control-layers,
|
||||
.leaflet-touch .leaflet-bar {
|
||||
border: 2px solid rgba(0,0,0,0.2);
|
||||
background-clip: padding-box;
|
||||
}
|
||||
|
||||
|
||||
/* popup */
|
||||
|
||||
.leaflet-popup {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.leaflet-popup-content-wrapper {
|
||||
padding: 1px;
|
||||
text-align: left;
|
||||
border-radius: 12px;
|
||||
}
|
||||
.leaflet-popup-content {
|
||||
margin: 13px 24px 13px 20px;
|
||||
line-height: 1.3;
|
||||
font-size: 13px;
|
||||
font-size: 1.08333em;
|
||||
min-height: 1px;
|
||||
}
|
||||
.leaflet-popup-content p {
|
||||
margin: 17px 0;
|
||||
margin: 1.3em 0;
|
||||
}
|
||||
.leaflet-popup-tip-container {
|
||||
width: 40px;
|
||||
height: 20px;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
margin-top: -1px;
|
||||
margin-left: -20px;
|
||||
overflow: hidden;
|
||||
pointer-events: none;
|
||||
}
|
||||
.leaflet-popup-tip {
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
padding: 1px;
|
||||
|
||||
margin: -10px auto 0;
|
||||
pointer-events: auto;
|
||||
|
||||
-webkit-transform: rotate(45deg);
|
||||
-moz-transform: rotate(45deg);
|
||||
-ms-transform: rotate(45deg);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
.leaflet-popup-content-wrapper,
|
||||
.leaflet-popup-tip {
|
||||
background: white;
|
||||
color: #333;
|
||||
box-shadow: 0 3px 14px rgba(0,0,0,0.4);
|
||||
}
|
||||
.leaflet-container a.leaflet-popup-close-button {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
border: none;
|
||||
text-align: center;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
font: 16px/24px Tahoma, Verdana, sans-serif;
|
||||
color: #757575;
|
||||
text-decoration: none;
|
||||
background: transparent;
|
||||
}
|
||||
.leaflet-container a.leaflet-popup-close-button:hover,
|
||||
.leaflet-container a.leaflet-popup-close-button:focus {
|
||||
color: #585858;
|
||||
}
|
||||
.leaflet-popup-scrolled {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.leaflet-oldie .leaflet-popup-content-wrapper {
|
||||
-ms-zoom: 1;
|
||||
}
|
||||
.leaflet-oldie .leaflet-popup-tip {
|
||||
width: 24px;
|
||||
margin: 0 auto;
|
||||
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
|
||||
filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
|
||||
}
|
||||
|
||||
.leaflet-oldie .leaflet-control-zoom,
|
||||
.leaflet-oldie .leaflet-control-layers,
|
||||
.leaflet-oldie .leaflet-popup-content-wrapper,
|
||||
.leaflet-oldie .leaflet-popup-tip {
|
||||
border: 1px solid #999;
|
||||
}
|
||||
|
||||
|
||||
/* div icon */
|
||||
|
||||
.leaflet-div-icon {
|
||||
background: #fff;
|
||||
border: 1px solid #666;
|
||||
}
|
||||
|
||||
|
||||
/* Tooltip */
|
||||
/* Base styles for the element that has a tooltip */
|
||||
.leaflet-tooltip {
|
||||
position: absolute;
|
||||
padding: 6px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #fff;
|
||||
border-radius: 3px;
|
||||
color: #222;
|
||||
white-space: nowrap;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
pointer-events: none;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.4);
|
||||
}
|
||||
.leaflet-tooltip.leaflet-interactive {
|
||||
cursor: pointer;
|
||||
pointer-events: auto;
|
||||
}
|
||||
.leaflet-tooltip-top:before,
|
||||
.leaflet-tooltip-bottom:before,
|
||||
.leaflet-tooltip-left:before,
|
||||
.leaflet-tooltip-right:before {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
border: 6px solid transparent;
|
||||
background: transparent;
|
||||
content: "";
|
||||
}
|
||||
|
||||
/* Directions */
|
||||
|
||||
.leaflet-tooltip-bottom {
|
||||
margin-top: 6px;
|
||||
}
|
||||
.leaflet-tooltip-top {
|
||||
margin-top: -6px;
|
||||
}
|
||||
.leaflet-tooltip-bottom:before,
|
||||
.leaflet-tooltip-top:before {
|
||||
left: 50%;
|
||||
margin-left: -6px;
|
||||
}
|
||||
.leaflet-tooltip-top:before {
|
||||
bottom: 0;
|
||||
margin-bottom: -12px;
|
||||
border-top-color: #fff;
|
||||
}
|
||||
.leaflet-tooltip-bottom:before {
|
||||
top: 0;
|
||||
margin-top: -12px;
|
||||
margin-left: -6px;
|
||||
border-bottom-color: #fff;
|
||||
}
|
||||
.leaflet-tooltip-left {
|
||||
margin-left: -6px;
|
||||
}
|
||||
.leaflet-tooltip-right {
|
||||
margin-left: 6px;
|
||||
}
|
||||
.leaflet-tooltip-left:before,
|
||||
.leaflet-tooltip-right:before {
|
||||
top: 50%;
|
||||
margin-top: -6px;
|
||||
}
|
||||
.leaflet-tooltip-left:before {
|
||||
right: 0;
|
||||
margin-right: -12px;
|
||||
border-left-color: #fff;
|
||||
}
|
||||
.leaflet-tooltip-right:before {
|
||||
left: 0;
|
||||
margin-left: -12px;
|
||||
border-right-color: #fff;
|
||||
}
|
||||
|
||||
/* Printing */
|
||||
|
||||
@media print {
|
||||
/* Prevent printers from removing background-images of controls. */
|
||||
.leaflet-control {
|
||||
-webkit-print-color-adjust: exact;
|
||||
print-color-adjust: exact;
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 696 B |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 618 B |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
@@ -0,0 +1,156 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
viewBox="0 0 600 60"
|
||||
height="60"
|
||||
width="600"
|
||||
id="svg4225"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="spritesheet.svg"
|
||||
inkscape:export-filename="/home/fpuga/development/upstream/icarto.Leaflet.draw/src/images/spritesheet-2x.png"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-ydpi="90">
|
||||
<metadata
|
||||
id="metadata4258">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs4256" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1056"
|
||||
id="namedview4254"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.3101852"
|
||||
inkscape:cx="237.56928"
|
||||
inkscape:cy="7.2419621"
|
||||
inkscape:window-x="1920"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg4225" />
|
||||
<g
|
||||
id="enabled"
|
||||
style="fill:#464646;fill-opacity:1">
|
||||
<g
|
||||
id="polyline"
|
||||
style="fill:#464646;fill-opacity:1">
|
||||
<path
|
||||
d="m 18,36 0,6 6,0 0,-6 -6,0 z m 4,4 -2,0 0,-2 2,0 0,2 z"
|
||||
id="path4229"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#464646;fill-opacity:1" />
|
||||
<path
|
||||
d="m 36,18 0,6 6,0 0,-6 -6,0 z m 4,4 -2,0 0,-2 2,0 0,2 z"
|
||||
id="path4231"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#464646;fill-opacity:1" />
|
||||
<path
|
||||
d="m 23.142,39.145 -2.285,-2.29 16,-15.998 2.285,2.285 z"
|
||||
id="path4233"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#464646;fill-opacity:1" />
|
||||
</g>
|
||||
<path
|
||||
id="polygon"
|
||||
d="M 100,24.565 97.904,39.395 83.07,42 76,28.773 86.463,18 Z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#464646;fill-opacity:1" />
|
||||
<path
|
||||
id="rectangle"
|
||||
d="m 140,20 20,0 0,20 -20,0 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#464646;fill-opacity:1" />
|
||||
<path
|
||||
id="circle"
|
||||
d="m 221,30 c 0,6.078 -4.926,11 -11,11 -6.074,0 -11,-4.922 -11,-11 0,-6.074 4.926,-11 11,-11 6.074,0 11,4.926 11,11 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#464646;fill-opacity:1" />
|
||||
<path
|
||||
id="marker"
|
||||
d="m 270,19 c -4.971,0 -9,4.029 -9,9 0,4.971 5.001,12 9,14 4.001,-2 9,-9.029 9,-14 0,-4.971 -4.029,-9 -9,-9 z m 0,12.5 c -2.484,0 -4.5,-2.014 -4.5,-4.5 0,-2.484 2.016,-4.5 4.5,-4.5 2.485,0 4.5,2.016 4.5,4.5 0,2.486 -2.015,4.5 -4.5,4.5 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#464646;fill-opacity:1" />
|
||||
<g
|
||||
id="edit"
|
||||
style="fill:#464646;fill-opacity:1">
|
||||
<path
|
||||
d="m 337,30.156 0,0.407 0,5.604 c 0,1.658 -1.344,3 -3,3 l -10,0 c -1.655,0 -3,-1.342 -3,-3 l 0,-10 c 0,-1.657 1.345,-3 3,-3 l 6.345,0 3.19,-3.17 -9.535,0 c -3.313,0 -6,2.687 -6,6 l 0,10 c 0,3.313 2.687,6 6,6 l 10,0 c 3.314,0 6,-2.687 6,-6 l 0,-8.809 -3,2.968"
|
||||
id="path4240"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#464646;fill-opacity:1" />
|
||||
<path
|
||||
d="m 338.72,24.637 -8.892,8.892 -2.828,0 0,-2.829 8.89,-8.89 z"
|
||||
id="path4242"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#464646;fill-opacity:1" />
|
||||
<path
|
||||
d="m 338.697,17.826 4,0 0,4 -4,0 z"
|
||||
transform="matrix(-0.70698336,-0.70723018,0.70723018,-0.70698336,567.55917,274.78273)"
|
||||
id="path4244"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#464646;fill-opacity:1" />
|
||||
</g>
|
||||
<g
|
||||
id="remove"
|
||||
style="fill:#464646;fill-opacity:1">
|
||||
<path
|
||||
d="m 381,42 18,0 0,-18 -18,0 0,18 z m 14,-16 2,0 0,14 -2,0 0,-14 z m -4,0 2,0 0,14 -2,0 0,-14 z m -4,0 2,0 0,14 -2,0 0,-14 z m -4,0 2,0 0,14 -2,0 0,-14 z"
|
||||
id="path4247"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#464646;fill-opacity:1" />
|
||||
<path
|
||||
d="m 395,20 0,-4 -10,0 0,4 -6,0 0,2 22,0 0,-2 -6,0 z m -2,0 -6,0 0,-2 6,0 0,2 z"
|
||||
id="path4249"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#464646;fill-opacity:1" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
id="disabled"
|
||||
transform="translate(120,0)"
|
||||
style="fill:#bbbbbb">
|
||||
<use
|
||||
xlink:href="#edit"
|
||||
id="edit-disabled"
|
||||
x="0"
|
||||
y="0"
|
||||
width="100%"
|
||||
height="100%" />
|
||||
<use
|
||||
xlink:href="#remove"
|
||||
id="remove-disabled"
|
||||
x="0"
|
||||
y="0"
|
||||
width="100%"
|
||||
height="100%" />
|
||||
</g>
|
||||
<path
|
||||
style="fill:none;stroke:#464646;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="circle-3"
|
||||
d="m 581.65725,30 c 0,6.078 -4.926,11 -11,11 -6.074,0 -11,-4.922 -11,-11 0,-6.074 4.926,-11 11,-11 6.074,0 11,4.926 11,11 z"
|
||||
inkscape:connector-curvature="0" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.4 KiB |
@@ -0,0 +1,325 @@
|
||||
/* ================================================================== */
|
||||
/* Toolbars
|
||||
/* ================================================================== */
|
||||
|
||||
.leaflet-draw-section {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.leaflet-draw-toolbar {
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.leaflet-draw-toolbar-top {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.leaflet-draw-toolbar-notop a:first-child {
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
|
||||
.leaflet-draw-toolbar-nobottom a:last-child {
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
.leaflet-draw-toolbar a {
|
||||
background-image: url('images/spritesheet.png');
|
||||
background-image: linear-gradient(transparent, transparent), url('images/spritesheet.svg');
|
||||
background-repeat: no-repeat;
|
||||
background-size: 300px 30px;
|
||||
background-clip: padding-box;
|
||||
}
|
||||
|
||||
.leaflet-retina .leaflet-draw-toolbar a {
|
||||
background-image: url('images/spritesheet-2x.png');
|
||||
background-image: linear-gradient(transparent, transparent), url('images/spritesheet.svg');
|
||||
}
|
||||
|
||||
.leaflet-draw a {
|
||||
display: block;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.leaflet-draw a .sr-only {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
/* Toolbar actions menu
|
||||
/* ================================================================== */
|
||||
|
||||
.leaflet-draw-actions {
|
||||
display: none;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
left: 26px; /* leaflet-draw-toolbar.left + leaflet-draw-toolbar.width */
|
||||
top: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-draw-actions {
|
||||
left: 32px;
|
||||
}
|
||||
|
||||
.leaflet-right .leaflet-draw-actions {
|
||||
right: 26px;
|
||||
left: auto;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-right .leaflet-draw-actions {
|
||||
right: 32px;
|
||||
left: auto;
|
||||
}
|
||||
|
||||
.leaflet-draw-actions li {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.leaflet-draw-actions li:first-child a {
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
.leaflet-draw-actions li:last-child a {
|
||||
-webkit-border-radius: 0 4px 4px 0;
|
||||
border-radius: 0 4px 4px 0;
|
||||
}
|
||||
|
||||
.leaflet-right .leaflet-draw-actions li:last-child a {
|
||||
-webkit-border-radius: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.leaflet-right .leaflet-draw-actions li:first-child a {
|
||||
-webkit-border-radius: 4px 0 0 4px;
|
||||
border-radius: 4px 0 0 4px;
|
||||
}
|
||||
|
||||
.leaflet-draw-actions a {
|
||||
background-color: #919187;
|
||||
border-left: 1px solid #AAA;
|
||||
color: #FFF;
|
||||
font: 11px/19px "Helvetica Neue", Arial, Helvetica, sans-serif;
|
||||
line-height: 28px;
|
||||
text-decoration: none;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-draw-actions a {
|
||||
font-size: 12px;
|
||||
line-height: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.leaflet-draw-actions-bottom {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.leaflet-draw-actions-top {
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
||||
.leaflet-draw-actions-top a,
|
||||
.leaflet-draw-actions-bottom a {
|
||||
height: 27px;
|
||||
line-height: 27px;
|
||||
}
|
||||
|
||||
.leaflet-draw-actions a:hover {
|
||||
background-color: #A0A098;
|
||||
}
|
||||
|
||||
.leaflet-draw-actions-top.leaflet-draw-actions-bottom a {
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
/* Draw toolbar
|
||||
/* ================================================================== */
|
||||
|
||||
.leaflet-draw-toolbar .leaflet-draw-draw-polyline {
|
||||
background-position: -2px -2px;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-draw-polyline {
|
||||
background-position: 0 -1px;
|
||||
}
|
||||
|
||||
.leaflet-draw-toolbar .leaflet-draw-draw-polygon {
|
||||
background-position: -31px -2px;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-draw-polygon {
|
||||
background-position: -29px -1px;
|
||||
}
|
||||
|
||||
.leaflet-draw-toolbar .leaflet-draw-draw-rectangle {
|
||||
background-position: -62px -2px;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-draw-rectangle {
|
||||
background-position: -60px -1px;
|
||||
}
|
||||
|
||||
.leaflet-draw-toolbar .leaflet-draw-draw-circle {
|
||||
background-position: -92px -2px;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-draw-circle {
|
||||
background-position: -90px -1px;
|
||||
}
|
||||
|
||||
.leaflet-draw-toolbar .leaflet-draw-draw-marker {
|
||||
background-position: -122px -2px;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-draw-marker {
|
||||
background-position: -120px -1px;
|
||||
}
|
||||
|
||||
.leaflet-draw-toolbar .leaflet-draw-draw-circlemarker {
|
||||
background-position: -273px -2px;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-draw-circlemarker {
|
||||
background-position: -271px -1px;
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
/* Edit toolbar
|
||||
/* ================================================================== */
|
||||
|
||||
.leaflet-draw-toolbar .leaflet-draw-edit-edit {
|
||||
background-position: -152px -2px;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-edit-edit {
|
||||
background-position: -150px -1px;
|
||||
}
|
||||
|
||||
.leaflet-draw-toolbar .leaflet-draw-edit-remove {
|
||||
background-position: -182px -2px;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-edit-remove {
|
||||
background-position: -180px -1px;
|
||||
}
|
||||
|
||||
.leaflet-draw-toolbar .leaflet-draw-edit-edit.leaflet-disabled {
|
||||
background-position: -212px -2px;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-edit-edit.leaflet-disabled {
|
||||
background-position: -210px -1px;
|
||||
}
|
||||
|
||||
.leaflet-draw-toolbar .leaflet-draw-edit-remove.leaflet-disabled {
|
||||
background-position: -242px -2px;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-edit-remove.leaflet-disabled {
|
||||
background-position: -240px -2px;
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
/* Drawing styles
|
||||
/* ================================================================== */
|
||||
|
||||
.leaflet-mouse-marker {
|
||||
background-color: #fff;
|
||||
cursor: crosshair;
|
||||
}
|
||||
|
||||
.leaflet-draw-tooltip {
|
||||
background: rgb(54, 54, 54);
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
border: 1px solid transparent;
|
||||
-webkit-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
color: #fff;
|
||||
font: 12px/18px "Helvetica Neue", Arial, Helvetica, sans-serif;
|
||||
margin-left: 20px;
|
||||
margin-top: -21px;
|
||||
padding: 4px 8px;
|
||||
position: absolute;
|
||||
visibility: hidden;
|
||||
white-space: nowrap;
|
||||
z-index: 6;
|
||||
}
|
||||
|
||||
.leaflet-draw-tooltip:before {
|
||||
border-right: 6px solid black;
|
||||
border-right-color: rgba(0, 0, 0, 0.5);
|
||||
border-top: 6px solid transparent;
|
||||
border-bottom: 6px solid transparent;
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 7px;
|
||||
left: -7px;
|
||||
}
|
||||
|
||||
.leaflet-error-draw-tooltip {
|
||||
background-color: #F2DEDE;
|
||||
border: 1px solid #E6B6BD;
|
||||
color: #B94A48;
|
||||
}
|
||||
|
||||
.leaflet-error-draw-tooltip:before {
|
||||
border-right-color: #E6B6BD;
|
||||
}
|
||||
|
||||
.leaflet-draw-tooltip-single {
|
||||
margin-top: -12px
|
||||
}
|
||||
|
||||
.leaflet-draw-tooltip-subtext {
|
||||
color: #f8d5e4;
|
||||
}
|
||||
|
||||
.leaflet-draw-guide-dash {
|
||||
font-size: 1%;
|
||||
opacity: 0.6;
|
||||
position: absolute;
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
/* Edit styles
|
||||
/* ================================================================== */
|
||||
|
||||
.leaflet-edit-marker-selected {
|
||||
background-color: rgba(254, 87, 161, 0.1);
|
||||
border: 4px dashed rgba(254, 87, 161, 0.6);
|
||||
-webkit-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
.leaflet-edit-move {
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
.leaflet-edit-resize {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
/* Old IE styles
|
||||
/* ================================================================== */
|
||||
|
||||
.leaflet-oldie .leaflet-draw-toolbar {
|
||||
border: 1px solid #999;
|
||||
}
|
||||
4774
typo3conf/ext/ods_osm/Resources/Public/JavaScript/Leaflet/leaflet-draw/leaflet.draw-src.js
vendored
Normal file
10
typo3conf/ext/ods_osm/Resources/Public/JavaScript/Leaflet/leaflet-draw/leaflet.draw.css
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
.leaflet-draw-section{position:relative}.leaflet-draw-toolbar{margin-top:12px}.leaflet-draw-toolbar-top{margin-top:0}.leaflet-draw-toolbar-notop a:first-child{border-top-right-radius:0}.leaflet-draw-toolbar-nobottom a:last-child{border-bottom-right-radius:0}.leaflet-draw-toolbar a{background-image:url('images/spritesheet.png');background-image:linear-gradient(transparent,transparent),url('images/spritesheet.svg');background-repeat:no-repeat;background-size:300px 30px;background-clip:padding-box}.leaflet-retina .leaflet-draw-toolbar a{background-image:url('images/spritesheet-2x.png');background-image:linear-gradient(transparent,transparent),url('images/spritesheet.svg')}
|
||||
.leaflet-draw a{display:block;text-align:center;text-decoration:none}.leaflet-draw a .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.leaflet-draw-actions{display:none;list-style:none;margin:0;padding:0;position:absolute;left:26px;top:0;white-space:nowrap}.leaflet-touch .leaflet-draw-actions{left:32px}.leaflet-right .leaflet-draw-actions{right:26px;left:auto}.leaflet-touch .leaflet-right .leaflet-draw-actions{right:32px;left:auto}.leaflet-draw-actions li{display:inline-block}
|
||||
.leaflet-draw-actions li:first-child a{border-left:0}.leaflet-draw-actions li:last-child a{-webkit-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.leaflet-right .leaflet-draw-actions li:last-child a{-webkit-border-radius:0;border-radius:0}.leaflet-right .leaflet-draw-actions li:first-child a{-webkit-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.leaflet-draw-actions a{background-color:#919187;border-left:1px solid #AAA;color:#FFF;font:11px/19px "Helvetica Neue",Arial,Helvetica,sans-serif;line-height:28px;text-decoration:none;padding-left:10px;padding-right:10px;height:28px}
|
||||
.leaflet-touch .leaflet-draw-actions a{font-size:12px;line-height:30px;height:30px}.leaflet-draw-actions-bottom{margin-top:0}.leaflet-draw-actions-top{margin-top:1px}.leaflet-draw-actions-top a,.leaflet-draw-actions-bottom a{height:27px;line-height:27px}.leaflet-draw-actions a:hover{background-color:#a0a098}.leaflet-draw-actions-top.leaflet-draw-actions-bottom a{height:26px;line-height:26px}.leaflet-draw-toolbar .leaflet-draw-draw-polyline{background-position:-2px -2px}.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-draw-polyline{background-position:0 -1px}
|
||||
.leaflet-draw-toolbar .leaflet-draw-draw-polygon{background-position:-31px -2px}.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-draw-polygon{background-position:-29px -1px}.leaflet-draw-toolbar .leaflet-draw-draw-rectangle{background-position:-62px -2px}.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-draw-rectangle{background-position:-60px -1px}.leaflet-draw-toolbar .leaflet-draw-draw-circle{background-position:-92px -2px}.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-draw-circle{background-position:-90px -1px}
|
||||
.leaflet-draw-toolbar .leaflet-draw-draw-marker{background-position:-122px -2px}.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-draw-marker{background-position:-120px -1px}.leaflet-draw-toolbar .leaflet-draw-draw-circlemarker{background-position:-273px -2px}.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-draw-circlemarker{background-position:-271px -1px}.leaflet-draw-toolbar .leaflet-draw-edit-edit{background-position:-152px -2px}.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-edit-edit{background-position:-150px -1px}
|
||||
.leaflet-draw-toolbar .leaflet-draw-edit-remove{background-position:-182px -2px}.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-edit-remove{background-position:-180px -1px}.leaflet-draw-toolbar .leaflet-draw-edit-edit.leaflet-disabled{background-position:-212px -2px}.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-edit-edit.leaflet-disabled{background-position:-210px -1px}.leaflet-draw-toolbar .leaflet-draw-edit-remove.leaflet-disabled{background-position:-242px -2px}.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-edit-remove.leaflet-disabled{background-position:-240px -2px}
|
||||
.leaflet-mouse-marker{background-color:#fff;cursor:crosshair}.leaflet-draw-tooltip{background:#363636;background:rgba(0,0,0,0.5);border:1px solid transparent;-webkit-border-radius:4px;border-radius:4px;color:#fff;font:12px/18px "Helvetica Neue",Arial,Helvetica,sans-serif;margin-left:20px;margin-top:-21px;padding:4px 8px;position:absolute;visibility:hidden;white-space:nowrap;z-index:6}.leaflet-draw-tooltip:before{border-right:6px solid black;border-right-color:rgba(0,0,0,0.5);border-top:6px solid transparent;border-bottom:6px solid transparent;content:"";position:absolute;top:7px;left:-7px}
|
||||
.leaflet-error-draw-tooltip{background-color:#f2dede;border:1px solid #e6b6bd;color:#b94a48}.leaflet-error-draw-tooltip:before{border-right-color:#e6b6bd}.leaflet-draw-tooltip-single{margin-top:-12px}.leaflet-draw-tooltip-subtext{color:#f8d5e4}.leaflet-draw-guide-dash{font-size:1%;opacity:.6;position:absolute;width:5px;height:5px}.leaflet-edit-marker-selected{background-color:rgba(254,87,161,0.1);border:4px dashed rgba(254,87,161,0.6);-webkit-border-radius:4px;border-radius:4px;box-sizing:content-box}
|
||||
.leaflet-edit-move{cursor:move}.leaflet-edit-resize{cursor:pointer}.leaflet-oldie .leaflet-draw-toolbar{border:1px solid #999}
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"rules": {
|
||||
"camelcase": 0,
|
||||
"quotes": [2, "single", "avoid-escape"],
|
||||
"no-mixed-spaces-and-tabs": [2, "smart-tabs"],
|
||||
"space-before-function-paren": 2,
|
||||
"space-in-parens": 2,
|
||||
"object-curly-spacing": [2, "never"],
|
||||
"array-bracket-spacing": 2,
|
||||
"computed-property-spacing": 2,
|
||||
"space-before-blocks": 2,
|
||||
"keyword-spacing": 2,
|
||||
"no-lonely-if": 2,
|
||||
"comma-style": 2,
|
||||
"no-underscore-dangle": 0,
|
||||
"no-constant-condition": 0,
|
||||
"no-multi-spaces": 0,
|
||||
"strict": 0,
|
||||
"key-spacing": 0,
|
||||
"no-shadow": 0,
|
||||
"no-unused-vars": 2
|
||||
},
|
||||
"globals": {
|
||||
"L": true,
|
||||
"module": false,
|
||||
"define": false,
|
||||
"require": true
|
||||
},
|
||||
"env": {
|
||||
"browser": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
.fullscreen-icon { background-image: url(icon-fullscreen.svg); background-size:26px 52px; }
|
||||
.fullscreen-icon.leaflet-fullscreen-on { background-position:0 -26px; }
|
||||
.leaflet-touch .fullscreen-icon { background-position: 2px 2px; }
|
||||
.leaflet-touch .fullscreen-icon.leaflet-fullscreen-on { background-position: 2px -24px; }
|
||||
/* one selector per rule as explained here : http://www.sitepoint.com/html5-full-screen-api/ */
|
||||
.leaflet-container:-webkit-full-screen { width: 100% !important; height: 100% !important; z-index: 99999; }
|
||||
.leaflet-container:-ms-fullscreen { width: 100% !important; height: 100% !important; z-index: 99999; }
|
||||
.leaflet-container:full-screen { width: 100% !important; height: 100% !important; z-index: 99999; }
|
||||
.leaflet-container:fullscreen { width: 100% !important; height: 100% !important; z-index: 99999; }
|
||||
.leaflet-pseudo-fullscreen { position: fixed !important; width: 100% !important; height: 100% !important; top: 0px !important; left: 0px !important; z-index: 99999; }
|
||||
345
typo3conf/ext/ods_osm/Resources/Public/JavaScript/Leaflet/leaflet-fullscreen/Control.FullScreen.js
vendored
Normal file
@@ -0,0 +1,345 @@
|
||||
/*!
|
||||
* Based on package 'screenfull'
|
||||
* v5.2.0 - 2021-11-03
|
||||
* (c) Sindre Sorhus; MIT License
|
||||
* Added definition for using screenfull as an amd module
|
||||
* Must be placed before the definition of leaflet.fullscreen
|
||||
* as it is required by that
|
||||
*/
|
||||
(function (root, factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define('screenfull', factory);
|
||||
} else if (typeof module === 'object' && module.exports) {
|
||||
module.exports.screenfull = factory();
|
||||
} else {
|
||||
// Save 'screenfull' into global window variable
|
||||
root.screenfull = factory();
|
||||
}
|
||||
}(typeof self !== 'undefined' ? self : this, function () {
|
||||
'use strict';
|
||||
|
||||
var document = typeof window !== 'undefined' && typeof window.document !== 'undefined' ? window.document : {};
|
||||
|
||||
var fn = (function () {
|
||||
var val;
|
||||
|
||||
var fnMap = [
|
||||
[
|
||||
'requestFullscreen',
|
||||
'exitFullscreen',
|
||||
'fullscreenElement',
|
||||
'fullscreenEnabled',
|
||||
'fullscreenchange',
|
||||
'fullscreenerror'
|
||||
],
|
||||
// New WebKit
|
||||
[
|
||||
'webkitRequestFullscreen',
|
||||
'webkitExitFullscreen',
|
||||
'webkitFullscreenElement',
|
||||
'webkitFullscreenEnabled',
|
||||
'webkitfullscreenchange',
|
||||
'webkitfullscreenerror'
|
||||
|
||||
],
|
||||
// Old WebKit
|
||||
[
|
||||
'webkitRequestFullScreen',
|
||||
'webkitCancelFullScreen',
|
||||
'webkitCurrentFullScreenElement',
|
||||
'webkitCancelFullScreen',
|
||||
'webkitfullscreenchange',
|
||||
'webkitfullscreenerror'
|
||||
|
||||
],
|
||||
[
|
||||
'mozRequestFullScreen',
|
||||
'mozCancelFullScreen',
|
||||
'mozFullScreenElement',
|
||||
'mozFullScreenEnabled',
|
||||
'mozfullscreenchange',
|
||||
'mozfullscreenerror'
|
||||
],
|
||||
[
|
||||
'msRequestFullscreen',
|
||||
'msExitFullscreen',
|
||||
'msFullscreenElement',
|
||||
'msFullscreenEnabled',
|
||||
'MSFullscreenChange',
|
||||
'MSFullscreenError'
|
||||
]
|
||||
];
|
||||
|
||||
var i = 0;
|
||||
var l = fnMap.length;
|
||||
var ret = {};
|
||||
|
||||
for (; i < l; i++) {
|
||||
val = fnMap[i];
|
||||
if (val && val[1] in document) {
|
||||
for (i = 0; i < val.length; i++) {
|
||||
ret[fnMap[0][i]] = val[i];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
})();
|
||||
|
||||
var eventNameMap = {
|
||||
change: fn.fullscreenchange,
|
||||
error: fn.fullscreenerror
|
||||
};
|
||||
|
||||
var screenfull = {
|
||||
request: function (element, options) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
var onFullScreenEntered = function () {
|
||||
this.off('change', onFullScreenEntered);
|
||||
resolve();
|
||||
}.bind(this);
|
||||
|
||||
this.on('change', onFullScreenEntered);
|
||||
|
||||
element = element || document.documentElement;
|
||||
|
||||
var returnPromise = element[fn.requestFullscreen](options);
|
||||
|
||||
if (returnPromise instanceof Promise) {
|
||||
returnPromise.then(onFullScreenEntered).catch(reject);
|
||||
}
|
||||
}.bind(this));
|
||||
},
|
||||
exit: function () {
|
||||
return new Promise(function (resolve, reject) {
|
||||
if (!this.isFullscreen) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
var onFullScreenExit = function () {
|
||||
this.off('change', onFullScreenExit);
|
||||
resolve();
|
||||
}.bind(this);
|
||||
|
||||
this.on('change', onFullScreenExit);
|
||||
|
||||
var returnPromise = document[fn.exitFullscreen]();
|
||||
|
||||
if (returnPromise instanceof Promise) {
|
||||
returnPromise.then(onFullScreenExit).catch(reject);
|
||||
}
|
||||
}.bind(this));
|
||||
},
|
||||
toggle: function (element, options) {
|
||||
return this.isFullscreen ? this.exit() : this.request(element, options);
|
||||
},
|
||||
onchange: function (callback) {
|
||||
this.on('change', callback);
|
||||
},
|
||||
onerror: function (callback) {
|
||||
this.on('error', callback);
|
||||
},
|
||||
on: function (event, callback) {
|
||||
var eventName = eventNameMap[event];
|
||||
if (eventName) {
|
||||
document.addEventListener(eventName, callback, false);
|
||||
}
|
||||
},
|
||||
off: function (event, callback) {
|
||||
var eventName = eventNameMap[event];
|
||||
if (eventName) {
|
||||
document.removeEventListener(eventName, callback, false);
|
||||
}
|
||||
},
|
||||
raw: fn
|
||||
};
|
||||
|
||||
if (!fn) {
|
||||
return {isEnabled: false};
|
||||
} else {
|
||||
Object.defineProperties(screenfull, {
|
||||
isFullscreen: {
|
||||
get: function () {
|
||||
return Boolean(document[fn.fullscreenElement]);
|
||||
}
|
||||
},
|
||||
element: {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return document[fn.fullscreenElement];
|
||||
}
|
||||
},
|
||||
isEnabled: {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
// Coerce to boolean in case of old WebKit
|
||||
return Boolean(document[fn.fullscreenEnabled]);
|
||||
}
|
||||
}
|
||||
});
|
||||
return screenfull;
|
||||
}
|
||||
}));
|
||||
|
||||
/*!
|
||||
* leaflet.fullscreen
|
||||
*/
|
||||
(function (root, factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// define an AMD module that requires 'leaflet' and 'screenfull'
|
||||
// and resolve to an object containing leaflet and screenfull
|
||||
define('leafletFullScreen', ['leaflet', 'screenfull'], factory);
|
||||
} else if (typeof module === 'object' && module.exports) {
|
||||
// define a CommonJS module that requires 'leaflet' and 'screenfull'
|
||||
module.exports = factory(require('leaflet'), require('screenfull'));
|
||||
} else {
|
||||
// Assume 'leaflet' and 'screenfull' are loaded into global variable already
|
||||
factory(root.L, root.screenfull);
|
||||
}
|
||||
}(typeof self !== 'undefined' ? self : this, function (leaflet, screenfull) {
|
||||
'use strict';
|
||||
|
||||
leaflet.Control.FullScreen = leaflet.Control.extend({
|
||||
options: {
|
||||
position: 'topleft',
|
||||
title: 'Full Screen',
|
||||
titleCancel: 'Exit Full Screen',
|
||||
forceSeparateButton: false,
|
||||
forcePseudoFullscreen: false,
|
||||
fullscreenElement: false
|
||||
},
|
||||
|
||||
_screenfull: screenfull,
|
||||
|
||||
onAdd: function (map) {
|
||||
var className = 'leaflet-control-zoom-fullscreen', container, content = '';
|
||||
|
||||
if (map.zoomControl && !this.options.forceSeparateButton) {
|
||||
container = map.zoomControl._container;
|
||||
} else {
|
||||
container = leaflet.DomUtil.create('div', 'leaflet-bar');
|
||||
}
|
||||
|
||||
if (this.options.content) {
|
||||
content = this.options.content;
|
||||
} else {
|
||||
className += ' fullscreen-icon';
|
||||
}
|
||||
|
||||
this._createButton(this.options.title, className, content, container, this.toggleFullScreen, this);
|
||||
this._map.fullscreenControl = this;
|
||||
|
||||
this._map.on('enterFullscreen exitFullscreen', this._toggleState, this);
|
||||
|
||||
return container;
|
||||
},
|
||||
|
||||
onRemove: function () {
|
||||
leaflet.DomEvent
|
||||
.off(this.link, 'click', leaflet.DomEvent.stop)
|
||||
.off(this.link, 'click', this.toggleFullScreen, this);
|
||||
|
||||
if (this._screenfull.isEnabled) {
|
||||
leaflet.DomEvent
|
||||
.off(this._container, this._screenfull.raw.fullscreenchange, leaflet.DomEvent.stop)
|
||||
.off(this._container, this._screenfull.raw.fullscreenchange, this._handleFullscreenChange, this);
|
||||
|
||||
leaflet.DomEvent
|
||||
.off(document, this._screenfull.raw.fullscreenchange, leaflet.DomEvent.stop)
|
||||
.off(document, this._screenfull.raw.fullscreenchange, this._handleFullscreenChange, this);
|
||||
}
|
||||
},
|
||||
|
||||
_createButton: function (title, className, content, container, fn, context) {
|
||||
this.link = leaflet.DomUtil.create('a', className, container);
|
||||
this.link.href = '#';
|
||||
this.link.title = title;
|
||||
this.link.innerHTML = content;
|
||||
|
||||
this.link.setAttribute('role', 'button');
|
||||
this.link.setAttribute('aria-label', title);
|
||||
|
||||
L.DomEvent.disableClickPropagation(container);
|
||||
|
||||
leaflet.DomEvent
|
||||
.on(this.link, 'click', leaflet.DomEvent.stop)
|
||||
.on(this.link, 'click', fn, context);
|
||||
|
||||
if (this._screenfull.isEnabled) {
|
||||
leaflet.DomEvent
|
||||
.on(container, this._screenfull.raw.fullscreenchange, leaflet.DomEvent.stop)
|
||||
.on(container, this._screenfull.raw.fullscreenchange, this._handleFullscreenChange, context);
|
||||
|
||||
leaflet.DomEvent
|
||||
.on(document, this._screenfull.raw.fullscreenchange, leaflet.DomEvent.stop)
|
||||
.on(document, this._screenfull.raw.fullscreenchange, this._handleFullscreenChange, context);
|
||||
}
|
||||
|
||||
return this.link;
|
||||
},
|
||||
|
||||
toggleFullScreen: function () {
|
||||
var map = this._map;
|
||||
map._exitFired = false;
|
||||
if (map._isFullscreen) {
|
||||
if (this._screenfull.isEnabled && !this.options.forcePseudoFullscreen) {
|
||||
this._screenfull.exit();
|
||||
} else {
|
||||
leaflet.DomUtil.removeClass(this.options.fullscreenElement ? this.options.fullscreenElement : map._container, 'leaflet-pseudo-fullscreen');
|
||||
map.invalidateSize();
|
||||
}
|
||||
map.fire('exitFullscreen');
|
||||
map._exitFired = true;
|
||||
map._isFullscreen = false;
|
||||
}
|
||||
else {
|
||||
if (this._screenfull.isEnabled && !this.options.forcePseudoFullscreen) {
|
||||
this._screenfull.request(this.options.fullscreenElement ? this.options.fullscreenElement : map._container);
|
||||
} else {
|
||||
leaflet.DomUtil.addClass(this.options.fullscreenElement ? this.options.fullscreenElement : map._container, 'leaflet-pseudo-fullscreen');
|
||||
map.invalidateSize();
|
||||
}
|
||||
map.fire('enterFullscreen');
|
||||
map._isFullscreen = true;
|
||||
}
|
||||
},
|
||||
|
||||
_toggleState: function () {
|
||||
this.link.title = this._map._isFullscreen ? this.options.title : this.options.titleCancel;
|
||||
this._map._isFullscreen ? L.DomUtil.removeClass(this.link, 'leaflet-fullscreen-on') : L.DomUtil.addClass(this.link, 'leaflet-fullscreen-on');
|
||||
},
|
||||
|
||||
_handleFullscreenChange: function () {
|
||||
var map = this._map;
|
||||
map.invalidateSize();
|
||||
if (!this._screenfull.isFullscreen && !map._exitFired) {
|
||||
map.fire('exitFullscreen');
|
||||
map._exitFired = true;
|
||||
map._isFullscreen = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
leaflet.Map.include({
|
||||
toggleFullscreen: function () {
|
||||
this.fullscreenControl.toggleFullScreen();
|
||||
}
|
||||
});
|
||||
|
||||
leaflet.Map.addInitHook(function () {
|
||||
if (this.options.fullscreenControl) {
|
||||
this.addControl(leaflet.control.fullscreen(this.options.fullscreenControlOptions));
|
||||
}
|
||||
});
|
||||
|
||||
leaflet.control.fullscreen = function (options) {
|
||||
return new leaflet.Control.FullScreen(options);
|
||||
};
|
||||
|
||||
// must return an object containing also screenfull to make screenfull
|
||||
// available outside of this package, if used as an amd module,
|
||||
// as webpack cannot handle amd define with moduleid
|
||||
return {leaflet: leaflet, screenfull: screenfull};
|
||||
}));
|
||||
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2013, Bruno Bergot
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||