diff --git a/public/static/img/markers/m1.png b/public/static/img/markers/m1.png new file mode 100644 index 0000000..329ff52 Binary files /dev/null and b/public/static/img/markers/m1.png differ diff --git a/public/static/img/markers/m2.png b/public/static/img/markers/m2.png new file mode 100644 index 0000000..b999cbc Binary files /dev/null and b/public/static/img/markers/m2.png differ diff --git a/public/static/img/markers/m3.png b/public/static/img/markers/m3.png new file mode 100644 index 0000000..9f30b30 Binary files /dev/null and b/public/static/img/markers/m3.png differ diff --git a/public/static/img/markers/m4.png b/public/static/img/markers/m4.png new file mode 100644 index 0000000..0d3f826 Binary files /dev/null and b/public/static/img/markers/m4.png differ diff --git a/public/static/img/markers/m5.png b/public/static/img/markers/m5.png new file mode 100644 index 0000000..61387d2 Binary files /dev/null and b/public/static/img/markers/m5.png differ diff --git a/public/static/js/map_editor.js b/public/static/js/map_editor.js index 097b0d8..e966b73 100644 --- a/public/static/js/map_editor.js +++ b/public/static/js/map_editor.js @@ -7,7 +7,6 @@ description: null }, map: null, - markers: null, panorama: null, selectedMarker: null, added: {}, @@ -124,10 +123,7 @@ MapEditor.panorama.setVisible(false); if (marker.placeId) { - MapEditor.markers.removeLayer(MapEditor.selectedMarker); - MapEditor.map.addLayer(MapEditor.selectedMarker); - marker.setIcon(IconCollection.iconBlue); - marker.setZIndexOffset(2000); + MapEditor.map.changeMarkerIcon(marker, MapEditor.map.iconCollection.iconBlue); document.getElementById('deleteButton').style.display = 'block'; @@ -165,13 +161,13 @@ var placeId = MapEditor.selectedMarker.placeId if (places[placeId].id && !del) { - MapEditor.map.removeLayer(MapEditor.selectedMarker); - MapEditor.markers.addLayer(MapEditor.selectedMarker); - MapEditor.selectedMarker.setIcon(places[placeId].noPano ? IconCollection.iconRed : IconCollection.iconGreen); - MapEditor.selectedMarker.setZIndexOffset(1000); + MapEditor.map.changeMarkerIcon( + MapEditor.selectedMarker, + places[placeId].noPano ? MapEditor.map.iconCollection.iconRed : MapEditor.map.iconCollection.iconGreen + ); } else { delete places[placeId]; - MapEditor.map.removeLayer(MapEditor.selectedMarker); + MapEditor.map.removeMarker(MapEditor.selectedMarker); } document.getElementById('deleteButton').style.display = 'none'; @@ -310,42 +306,9 @@ var placeId = addedPlaces[i].id; places[tempId].id = placeId; } - }, - - // TODO: check whether marker is already existing on the map for the coordinates - // or alternatively block saving for matching coordinates - placeMarker: function (latlng) { - var marker = L.marker(latlng, { - icon: IconCollection.iconBlue, - zIndexOffset: 2000 - }) - .addTo(MapEditor.map) - .on('click', function () { - MapEditor.select(this); - }); - - MapEditor.select(marker); } }; - var IconCollection = { - iconGreen: L.icon({ - iconUrl: STATIC_ROOT + '/img/markers/marker-green.svg?rev' + REVISION, - iconSize: [24, 32], - iconAnchor: [12, 32] - }), - iconRed: L.icon({ - iconUrl: STATIC_ROOT + '/img/markers/marker-red.svg?rev=' + REVISION, - iconSize: [24, 32], - iconAnchor: [12, 32] - }), - iconBlue: L.icon({ - iconUrl: STATIC_ROOT + '/img/markers/marker-blue.svg?rev=' + REVISION, - iconSize: [24, 32], - iconAnchor: [12, 32] - }), - }; - var Util = { getHighResData: function () { if (window.devicePixelRatio >= 4) { @@ -384,52 +347,243 @@ } }; - MapEditor.map = L.map('map', { - zoomControl: false - }); + var LMapWrapper = { + map: null, + markers: null, + iconCollection: { + iconGreen: L.icon({ + iconUrl: STATIC_ROOT + '/img/markers/marker-green.svg?rev' + REVISION, + iconSize: [24, 32], + iconAnchor: [12, 32] + }), + iconRed: L.icon({ + iconUrl: STATIC_ROOT + '/img/markers/marker-red.svg?rev=' + REVISION, + iconSize: [24, 32], + iconAnchor: [12, 32] + }), + iconBlue: L.icon({ + iconUrl: STATIC_ROOT + '/img/markers/marker-blue.svg?rev=' + REVISION, + iconSize: [24, 32], + iconAnchor: [12, 32] + }) + }, - MapEditor.map.on('click', function (e) { - MapEditor.placeMarker(e.latlng); - }); + init: function (divId, places) { + LMapWrapper.map = L.map('map', { + zoomControl: false + }); - var highResData = Util.getHighResData(); + LMapWrapper.map.on('click', function (e) { + LMapWrapper.placeMarker(e.latlng); + }); - L.tileLayer(tileUrl, { - attribution: tileAttribution, - subdomains: '1234', - ppi: highResData.ppi, - tileSize: highResData.tileSize, - zoomOffset: highResData.zoomOffset, - minZoom: highResData.minZoom, - maxZoom: highResData.maxZoom - }).addTo(MapEditor.map); + var highResData = Util.getHighResData(); - MapEditor.map.fitBounds(L.latLngBounds({ lat: mapBounds.south, lng: mapBounds.west }, { lat: mapBounds.north, lng: mapBounds.east })); + L.tileLayer(tileUrl, { + attribution: tileAttribution, + subdomains: '1234', + ppi: highResData.ppi, + tileSize: highResData.tileSize, + zoomOffset: highResData.zoomOffset, + minZoom: highResData.minZoom, + maxZoom: highResData.maxZoom + }).addTo(LMapWrapper.map); - MapEditor.markers = L.markerClusterGroup({ - maxClusterRadius: 50 - }); + LMapWrapper.map.fitBounds(L.latLngBounds({ lat: mapBounds.south, lng: mapBounds.west }, { lat: mapBounds.north, lng: mapBounds.east })); - for (var placeId in places) { - if (!places.hasOwnProperty(placeId)) { - continue; + LMapWrapper.loadMarkers(places); + }, + + loadMarkers: function (places) { + + LMapWrapper.markers = L.markerClusterGroup({ + maxClusterRadius: 50 + }); + + for (var placeId in places) { + if (!places.hasOwnProperty(placeId)) { + continue; + } + + var place = places[placeId]; + + var marker = L.marker({ lat: place.lat, lng: place.lng }, { + icon: place.noPano ? LMapWrapper.iconCollection.iconRed : LMapWrapper.iconCollection.iconGreen, + zIndexOffset: 1000 + }) + .addTo(LMapWrapper.markers) + .on('click', function () { + MapEditor.select(this); + }); + + marker.placeId = place.id; + } + + LMapWrapper.map.addLayer(LMapWrapper.markers); + }, + + // TODO: check whether marker is already existing on the map for the coordinates + // or alternatively block saving for matching coordinates + placeMarker: function (latLng) { + var marker = L.marker(latLng, { + icon: LMapWrapper.iconCollection.iconBlue, + zIndexOffset: 2000 + }) + .addTo(LMapWrapper.map) + .on('click', function () { + MapEditor.select(this); + }); + + MapEditor.select(marker); + }, + + panTo: function (latLng) { + LMapWrapper.map.panTo(latLng); + }, + + invalidateSize: function (invalid) { + LMapWrapper.map.invalidateSize(invalid); + }, + + changeMarkerIcon: function (marker, icon) { + LMapWrapper.markers.removeLayer(marker); + LMapWrapper.map.addLayer(marker); + marker.setIcon(icon); + marker.setZIndexOffset(2000); + }, + + removeMarker: function (marker) { + LMapWrapper.map.removeLayer(marker); } + }; - var place = places[placeId]; + var GMapWrapper = { + map: null, + markers: null, + iconCollection: { + iconGreen: { + url: STATIC_ROOT + '/img/markers/marker-green.svg?rev' + REVISION, + scaledSize: new google.maps.Size(24, 32), // scaled size + origin: new google.maps.Point(0, 0), // origin + anchor: new google.maps.Point(12, 32) // anchor + }, + iconRed: { + url: STATIC_ROOT + '/img/markers/marker-red.svg?rev' + REVISION, + scaledSize: new google.maps.Size(24, 32), // scaled size + origin: new google.maps.Point(0, 0), // origin + anchor: new google.maps.Point(12, 32) // anchor + }, + iconBlue: { + url: STATIC_ROOT + '/img/markers/marker-blue.svg?rev' + REVISION, + scaledSize: new google.maps.Size(24, 32), // scaled size + origin: new google.maps.Point(0, 0), // origin + anchor: new google.maps.Point(12, 32) // anchor + } + }, - var marker = L.marker({ lat: place.lat, lng: place.lng }, { - icon: place.noPano ? IconCollection.iconRed : IconCollection.iconGreen, - zIndexOffset: 1000 - }) - .addTo(MapEditor.markers) - .on('click', function () { + init: function (divId, places) { + GMapWrapper.map = new google.maps.Map(document.getElementById(divId), { + center: { lat: 48.2207779, lng: 16.3098489 }, + zoom: 2, + fullscreenControl: false, + zoomControl: true, + zoomControlOptions: { + position: google.maps.ControlPosition.LEFT_BOTTOM + }, + streetViewControl: true, + streetViewControlOptions: { + position: google.maps.ControlPosition.LEFT_BOTTOM + }, + draggableCursor: 'crosshair' + }); + + GMapWrapper.map.addListener('click', function (mapsMouseEvent) { + GMapWrapper.placeMarker({ + lat: mapsMouseEvent.latLng.lat(), + lng: mapsMouseEvent.latLng.lng() + }); + }); + + GMapWrapper.loadMarkers(places); + }, + + loadMarkers: function (places) { + GMapWrapper.markers = new MarkerClusterer(GMapWrapper.map, [], { + imagePath: STATIC_ROOT + '/img/markers/m', + imageExtension: 'png?rev' + REVISION + }); + + for (var placeId in places) { + if (!places.hasOwnProperty(placeId)) { + continue; + } + + var place = places[placeId]; + + var marker = new google.maps.Marker({ + position: { + lat: place.lat, + lng: place.lng + }, + icon: place.noPano ? GMapWrapper.iconCollection.iconRed : GMapWrapper.iconCollection.iconGreen + }); + + marker.getLatLng = function () { return { lat: this.getPosition().lat(), lng: this.getPosition().lng() } }; + marker.setLatLng = function (coords) { this.setPosition(coords) }; + + marker.addListener('click', function () { + MapEditor.select(this); + }); + + marker.placeId = place.id; + + GMapWrapper.markers.addMarker(marker); + } + }, + + // TODO: check whether marker is already existing on the map for the coordinates + // or alternatively block saving for matching coordinates + placeMarker: function (latLng) { + var marker = new google.maps.Marker({ + map: GMapWrapper.map, + position: latLng, + icon: GMapWrapper.iconCollection.iconBlue, + }); + + marker.getLatLng = function () { return { lat: this.getPosition().lat(), lng: this.getPosition().lng() } }; + marker.setLatLng = function (coords) { this.setPosition(coords) }; + + marker.addListener('click', function () { MapEditor.select(this); }); - marker.placeId = place.id; - } + GMapWrapper.markers.addMarker(marker); - MapEditor.map.addLayer(MapEditor.markers); + MapEditor.select(marker); + }, + + panTo: function (latLng) { + GMapWrapper.map.panTo(latLng); + }, + + invalidateSize: function (invalid) { + if (invalid) { + google.maps.event.trigger(GMapWrapper.map, 'resize'); + } + }, + + changeMarkerIcon: function (marker, icon) { + marker.setIcon(icon); + }, + + removeMarker: function (marker) { + GMapWrapper.markers.removeMarker(marker); + } + }; + + // MapEditor.map = LMapWrapper; + MapEditor.map = GMapWrapper; + MapEditor.map.init('map', places); MapEditor.panorama = new google.maps.StreetViewPanorama(document.getElementById('panorama'), { // switch off fullscreenControl because positioning doesn't work @@ -478,7 +632,7 @@ var coordinates = Util.extractCoordinates(coordinatesStr); if (coordinates.valid) { - MapEditor.placeMarker(coordinates.latlng); + MapEditor.map.placeMarker(coordinates.latlng); } }; @@ -491,7 +645,7 @@ jumpButton.disabled = false; if (e.key == 'Enter') { - MapEditor.placeMarker(coordinates.latlng); + MapEditor.map.placeMarker(coordinates.latlng); } } else { diff --git a/views/admin/map_editor.php b/views/admin/map_editor.php index c6de87b..4a42eee 100644 --- a/views/admin/map_editor.php +++ b/views/admin/map_editor.php @@ -6,6 +6,7 @@ @js(node_modules/leaflet/dist/leaflet.js) @js(node_modules/leaflet.markercluster/dist/leaflet.markercluster.js) @js(https://maps.googleapis.com/maps/api/js?key=) +@js(https://unpkg.com/@googlemaps/markerclustererplus/dist/index.min.js) @js(js/map_editor.js) @extends(templates/layout_full)