// Init vars var selectedFeature = null; var ignApiKey = "1121xe4cz6cemsslzliyr0cm"; var mapId = "map"; var selectedLayer = L.layerGroup(); // BASE LAYERS var OpenStreetMap = new L.TileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {alias : 'OpenStreetMap', maxNativeZoom: 19, maxZoom: 22, attribution: 'Map data © OpenStreetMap contributors' }) ; var osm_gray = new L.TileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {alias : 'osm_gray', className: 'sysma-leaflet-tile-greyscale', maxZoom: 20, attribution: 'Map data © OpenStreetMap contributors' }) ; var orthophotos = new L.TileLayer("https://data.geopf.fr/wmts?service=WMTS&request=GetTile&version=1.0.0&tilematrixset=PM&tilematrix={z}&tilecol={x}&tilerow={y}&layer=ORTHOIMAGERY.ORTHOPHOTOS&format=image/jpeg&style=normal", {alias : 'orthophotos', maxNativeZoom: 19, maxZoom: 22, attribution: '© IGN' }) ; var orthophotos1950_1965 = new L.TileLayer("https://data.geopf.fr/wmts?service=WMTS&request=GetTile&version=1.0.0&tilematrixset=PM&tilematrix={z}&tilecol={x}&tilerow={y}&layer=ORTHOIMAGERY.ORTHOPHOTOS.1950-1965&format=image/png&style=normal", {alias : 'orthophotos1950_1965', attribution: '© IGN' }) ; var orthophotosirc = new L.TileLayer("https://data.geopf.fr/wmts?service=WMTS&request=GetTile&version=1.0.0&tilematrixset=PM&tilematrix={z}&tilecol={x}&tilerow={y}&layer=ORTHOIMAGERY.ORTHOPHOTOS.IRC&format=image/jpeg&style=normal", {alias : 'orthophotosirc', attribution: '© IGN' }) ; // OTHER BASE LAYERS var limites_admin = new L.TileLayer("https://data.geopf.fr/wmts?service=WMTS&request=GetTile&version=1.0.0&tilematrixset=PM&tilematrix={z}&tilecol={x}&tilerow={y}&layer=LIMITES_ADMINISTRATIVES_EXPRESS.LATEST&format=image/png&style=normal", {alias : 'limites_admin', attribution: '© IGN' }) ; var cadastre = new L.TileLayer("https://data.geopf.fr/wmts?service=WMTS&request=GetTile&version=1.0.0&tilematrixset=PM&tilematrix={z}&tilecol={x}&tilerow={y}&layer=CADASTRALPARCELS.PARCELS&format=image/png&STYLE=bdparcellaire", {alias : 'cadastre', maxZoom: 21, attribution: '© IGN' }) ; var cours_eau_ddtm_complete = new L.tileLayer.wms("https://geobretagne.fr/geoserver/ddtm35/wms?", {alias : 'cours_eau_ddtm_complete', layers:'l_carto_cours_eau_l_035', transparent:true, format:'image/png', attribution: 'DDTM35', maxNativeZoom: 19, maxZoom: 22, }) ; var cours_eau_ddtm_progressive = new L.tileLayer.wms("https://geobretagne.fr/geoserver/ddtm35/wms?", {alias : 'cours_eau_ddtm_progressive', layers:'l_ce_carte_progressive_l_35', transparent:true, format:'image/png', attribution: 'DDTM35', maxNativeZoom: 19, maxZoom: 22, }) ; var topage = new L.tileLayer.wms("https://services.sandre.eaufrance.fr/geo/topage", {alias : 'topage', layers:'CoursEau_FXX', transparent:true, format:'image/png', attribution: 'SANDRE' }) ; var inventaire_national_plan_deau = new L.TileLayer("https://data.geopf.fr/wmts?service=WMTS&request=GetTile&version=1.0.0&tilematrixset=PM&tilematrix={z}&tilecol={x}&tilerow={y}&layer=INPE&format=image/png&style=INPE", {alias : 'inventaire_national_plan_deau', }) ; var prob_zh_metrop_vf = new L.tileLayer.wms("http://wms.reseau-zones-humides.org/cgi-bin/wmsfma?service=WMS&request=GetMap&version=1.3.0", {alias : 'prob_zh_metrop_vf', layers:'Prob_ZH_metrop_vf', format:'image/png', attribution: '© PatriNat' }) ; var etat_riviere = new L.TileLayer("https://eaurmc.lizmap.com/map/index.php/lizmap/service?repository=eaurmc&project=appli_qualite_riviere&LAYERS=masse_eau_appli_qualite&STYLES=défaut&VERSION=1.0.0&EXCEPTIONS=application/vnd.ogc.se_inimage&FORMAT=image/png&DPI=96&SERVICE=WMTS&REQUEST=GetTile&LAYER=masse_eau_appli_qualite&STYLE=default&TILEMATRIXSET=EPSG:3857&tilematrix={z}&tilecol={x}&tilerow={y}", {alias : 'etat_riviere', maxZoom: 23, transparent:true, attribution: '© AELB-RMC' }) ; var ENS35 = new L.tileLayer.wms("https://geobretagne.fr/geoserver/cd35/wms", {alias : 'ENS35', maxNativeZoom: 20, maxZoom: 22, layers:'site_espace_naturel_protege_poly_35', transparent:true, format:'image/png',style:'blue' }) ; var ZPENVDEP = new L.tileLayer.wms("https://geobretagne.fr/geoserver/cd35/wms", {alias : 'ZPENVDEP', maxNativeZoom: 20, maxZoom: 22, layers:'zone_preemption_ens_35', transparent:true, format:'image/png' }) ; var AFAFE = new L.tileLayer.wms("https://geobretagne.fr/geoserver/cd35/wms", {alias : 'AFAFE', maxNativeZoom: 20, maxZoom: 22, layers:'perimetres_afafe', transparent:true, format:'image/png' }) ; var landuse_2023 = new L.TileLayer("https://data.geopf.fr/wmts?service=WMTS&request=GetTile&version=1.0.0&tilematrixset=PM&tilematrix={z}&tilecol={x}&tilerow={y}&layer=LANDUSE.AGRICULTURE2023&format=image/png&style=normal", {alias : 'landuse_2023', attribution: '© IGN' }) ; var carte_forestiere_v2 = new L.TileLayer("https://data.geopf.fr/wmts?service=WMTS&request=GetTile&version=1.0.0&tilematrixset=PM&tilematrix={z}&tilecol={x}&tilerow={y}&layer=LANDCOVER.FORESTINVENTORY.V2&format=image/png&style=normal", {alias : 'carte_forestiere_v2', attribution: '© IGN' }) ; var drawnItems = new L.FeatureGroup(); // LEAFLET MAP INIT var map = L.map(mapId, { center: new L.LatLng(48.03,-1.77), zoom:9, zoomDelta: 0.25, zoomSnap: 0.25, maxZoom: 22, editable:true, editOptions:{ featuresLayer: drawnItems }, layers: [OpenStreetMap, ] }); var baseLayers = { "Open\u0020Street\u0020Map":OpenStreetMap, "Open\u0020Street\u0020Map\u0020N\u0026B":osm_gray, "OrthoPhotos\u0020\u0028dernier\u0020mill\u00E9sime\u0029":orthophotos, "OrthoPhotos\u0020\u00281950\u002D1965\u0029":orthophotos1950_1965, "OrthoPhotos\u0020IRC":orthophotosirc, } ; var otherBaseLayers = { "Limites\u0020administratives":limites_admin, "Cadastre":cadastre, "Cours\u0020d\u0027eau\u0020DDTM\u002035\u0020\u0028carto\u0020compl\u00E8te\u0029":cours_eau_ddtm_complete, "Cours\u0020d\u0027eau\u0020DDTM\u002035\u0020\u0028carto\u0020progressive\u0029":cours_eau_ddtm_progressive, "Cours\u0020d\u0027eau\u0020BD\u0020Topage":topage, "Inventaire\u0020national\u0020des\u0020plans\u0020d\u0027eau":inventaire_national_plan_deau, "Cartographie\u0020nationale\u0020des\u0020milieux\u0020humides":prob_zh_metrop_vf, "Etat\u0020\u00E9cologique\u0020des\u0020rivi\u00E8res\u0020\u0028DCE\u0029":etat_riviere, "Espaces\u0020Naturels\u0020Sensibles\u0020d\u0027Ille\u002Det\u002DVilaine":ENS35, "Zones\u0020de\u0020pr\u00E9emption\u0020environnementales\u0020d\u00E9partementales":ZPENVDEP, "P\u00E9rim\u00E8tres\u0020des\u0020op\u00E9rations\u0020d\u0027AFAFE":AFAFE, "Landuse\u0020RPG\u00202023":landuse_2023, "Carte\u0020foresti\u00E8re\u0020V2\u0020\u00282016\u002D...\u0029":carte_forestiere_v2, } ; // Layer control L.control.layers(baseLayers, otherBaseLayers, {position: 'topleft'}).addTo(map); // Scalbar L.control.scale({'imperial':false, 'metric':true, 'position':'bottomright'}).addTo(map); // Locate control L.control.locate().addTo(map); // DRAW var sysmaGroup = new L.FeatureGroup(); map.addLayer(sysmaGroup); map.addLayer(drawnItems); drawnItems.bringToFront(); // other tools // SYSMA TOOL BOX ///////////////////////////////////////////////////////////////////// var sysmaToolBoxIsOpened = false ; var selectionMode = false ; L.Control.sysmaToolsButton = L.Control.extend({ options: { position: 'topleft' }, onAdd: function (map) { var container = L.DomUtil.create('div', 'leaflet-bar leaflet-control leaflet-sysma-toolbox-control'); container.id = 'sysmaToolBox' ; var button = L.DomUtil.create('a', 'leaflet-control-button leaflet-sysma-toolbox-button', container); L.DomEvent.disableClickPropagation(button); L.DomEvent.on(container, 'click', function(){ openCloseSysmaToolbox(); }); container.title = "Sysma ToolBox"; return container; }, onRemove: function(map) {}, }); L.control.sysmaTools = function(opts) { return new L.Control.sysmaToolsButton(opts); } L.control.sysmaTools({ position: 'topleft' }).addTo(map); function toggleSelectionMode() { setSelectionMode(!selectionMode) } function setSelectionMode(onOff) { if (onOff) { selectionMode = true ; drawnItems.clearLayers(); console.log('Selection mode On') ; enableDraw('ST_Polygon',null) $('.leaflet-selection-button').attr('style', 'background-color : #000 !important') ; } else { selectionMode = false ; map.editTools.stopDrawing() ; console.log('Selection mode Off') ; $('.leaflet-selection-button').attr('style', 'background-color : #ccc !important') ; } } function openCloseSysmaToolbox() { // MEASURE CONTROL if (sysmaToolBoxIsOpened == false) { map.measureControl = new L.Control.Measure({ position:'topleft', primaryLengthUnit: 'meters', secondaryLengthUnit: undefined, primaryAreaUnit: 'hectares', secondaryAreaUnit : 'sqmeters', activeColor: '#ff0000', completedColor: '#FF3333', localization: 'fr' }) ; map.addControl(map.measureControl) } else { map.measureControl.remove() ; } // SEARCH Tool if (sysmaToolBoxIsOpened == false) { map.searchBtn = new L.Control.Search({ url: 'https://nominatim.openstreetmap.org/search?format=json&q={s}', jsonpParam: 'json_callback', propertyName: 'display_name', propertyLoc: ['lat', 'lon'], markerLocation: true, autoCollapse: true, autoType: false, minLength: 2 }) ; map.addControl(map.searchBtn); } else { map.searchBtn.remove() ; } // COORDS TOOL if (sysmaToolBoxIsOpened == false) { coordBtnConstructor = L.Control.extend({ options: { position: 'topleft' }, onAdd: function (map) { map.coordBtn = this; var container = L.DomUtil.create('div', 'leaflet-bar leaflet-control leaflet-coord-control'); var button = L.DomUtil.create('a', 'leaflet-control-button leaflet-coord-button text-inactive', container); button.id = 'iconCoord' ; L.DomEvent.disableClickPropagation(container); L.DomEvent.on(container, 'click', function(){ $('#iconCoord').toggleClass('text-inactive'); groupCoord.clearLayers(); if (!$('#iconRpg').hasClass('text-inactive')) { $('#iconRpg').toggleClass('text-inactive'); } if (!$('#iconCad').hasClass('text-inactive')) { $('#iconCad').toggleClass('text-inactive'); } setSelectionMode(false) }); container.title = "Afficher les coordonnées de la carte"; return container; }, onRemove: function(map) { groupCoord.clearLayers(); }, }); var coordBtn = new coordBtnConstructor() ; coordBtn.addTo(map); } else { if (map.coordBtn) { console.log('Close Coord Tool') ; map.coordBtn.remove() ; } } // SELECTION TOOL if (sysmaToolBoxIsOpened == false) { selectionBtnConstructor = L.Control.extend({ options: { position: 'topleft' }, onAdd: function (map) { map.selectBtn = this; var container = L.DomUtil.create('div', 'leaflet-bar leaflet-control leaflet-selection-control'); var button = L.DomUtil.create('a', 'leaflet-control-button leaflet-selection-button', container); L.DomEvent.disableClickPropagation(button); L.DomEvent.on(container, 'click', function(){ toggleSelectionMode(); if (!$('#iconCad').hasClass('text-inactive')) { $('#iconCad').toggleClass('text-inactive'); } if (!$('#iconRpg').hasClass('text-inactive')) { $('#iconRpg').toggleClass('text-inactive'); } if (!$('#iconCoord').hasClass('text-inactive')) { $('#iconCoord').toggleClass('text-inactive'); } }); container.title = "Zone de sélection"; return container; }, onRemove: function(map) {}, }); var selectBtn = new selectionBtnConstructor() ; selectBtn.addTo(map); } else { if (map.selectBtn) { console.log('Close Selection Tool') ; map.selectBtn.remove() ; } } // RPG TOOL if (sysmaToolBoxIsOpened == false) { console.log('Open Sysma Tool Box') ; sysmaToolBoxIsOpened = true ; } else { console.log('Close Sysma Tool Box') ; sysmaToolBoxIsOpened = false ; } } // Editable Events function enableDraw(type,snapLayer,mode = 'classic') { selectedLayer.remove() ; selectedLayer.clearLayers() ; //console.log(snapLayer); if (snapLayer !== null) { var snap = new L.Handler.MarkerSnap(map, null, { snapDistance : 15 }); //console.log('snapping is on') ; //console.log(map._layers[snapLayer]) ; snap.addGuideLayer(map._layers[snapLayer]); var snapMarker = L.marker(map.getCenter(), { icon: map.editTools.createVertexIcon({className: 'leaflet-div-icon leaflet-drawing-icon'}), opacity: 1, zIndexOffset: 1000 }); snap.watchMarker(snapMarker); map.on('editable:vertex:dragstart', function (e) { snap.watchMarker(e.vertex); }); map.on('editable:vertex:dragend', function (e) { snap.unwatchMarker(e.vertex); }); map.on('editable:drawing:start', function () { this.on('mousemove', followMouse); }); map.on('editable:drawing:end', function () { this.off('mousemove', followMouse); snapMarker.remove(); }); map.on('editable:drawing:cancel', function () { snap.disable() ; this.off('mousemove', followMouse); snapMarker.remove(); }); map.on('editable:drawing:click', function (e) { // Leaflet copy event data to another object when firing, // so the event object we have here is not the one fired by // Leaflet.Editable; it's not a deep copy though, so we can change // the other objects that have a reference here. var latlng = snapMarker.getLatLng(); e.latlng.lat = latlng.lat; e.latlng.lng = latlng.lng; }); snapMarker.on('snap', function (e) { snapMarker.addTo(map); }); snapMarker.on('unsnap', function (e) { snapMarker.remove(); }); var followMouse = function (e) { snapMarker.setLatLng(e.latlng); } } createMode = mode ; console.log('createMode'+createMode) ; if (type === 'ST_Point') { map.editTools.startMarker(); } else if (type === 'ST_Linestring') { map.editTools.startPolyline(); } else if (type === 'ST_Polygon') { map.editTools.startPolygon(); } } // tracking continue mode var cont = 0 ; map.on('editable:drawing:commit', function (e) { map.editTools.stopDrawing() ; if (cont === 0) { //console.log(e) ; e.layer.editor.disable() ; layer = e.layer; var shape = layer.toGeoJSON(); var shape_for_db = JSON.stringify(shape); var data = JSON.parse(shape_for_db); openClose('rightColumn', '60%', 'map', '100%'); $('#infos').hide(150); $('#objet').show(150); if (selectionMode) { sendData('geom=' + data.geometry.coordinates + '&selectionMode='+selectionMode, 'https\u003A\/\/ille\u002Det\u002Dvilaine.sysma.io\/selection\u002Dgeo', 'objet', null); setSelectionMode(false) ; } else { if (createMode !== undefined && createMode==='complete') { sendData('geom=' + data.geometry.coordinates, 'https\u003A\/\/ille\u002Det\u002Dvilaine.sysma.io\/objet\/create\u002Dcomplete', 'objet', null); } else { sendData('geom=' + data.geometry.coordinates, 'https\u003A\/\/ille\u002Det\u002Dvilaine.sysma.io\/objet\/create', 'objet', null); } } //sendData(null, "https\u003A\/\/ille\u002Det\u002Dvilaine.sysma.io\/layermanager", "infos", event); } else { //console.log('commit with continue = true') ; cont = 0 ; } }); // continue mode, Ctrl + click map.on('editable:vertex:ctrlclick editable:vertex:metakeyclick', function (e) { cont = 1 ; e.vertex.continue(); }); // editable Ctrl Z var Z = 90, latlng, redoBuffer = [], onKeyDown = function (e) { if (e.keyCode == Z) { if (!this.editTools._drawingEditor) return; if (e.shiftKey) { if (redoBuffer.length) this.editTools._drawingEditor.push(redoBuffer.pop()); } else { latlng = this.editTools._drawingEditor.pop(); if (latlng) redoBuffer.push(latlng); } } }; L.DomEvent.addListener(document, 'keydown', onKeyDown, map); map.on('editable:drawing:end', function () { redoBuffer = []; }); // Update user's center and zoom value on each pan and zoom map.on('moveend', function (e) { //console.log('moveend') ; $('#center').val(map.getCenter()) ; $('#zoom').val(map.getZoom()) ; console.log(e); sendData('centre=' + String(map.getCenter()).replace(" ","") + '&zoom=' + map.getZoom(), 'https\u003A\/\/ille\u002Det\u002Dvilaine.sysma.io\/update\u002Dmap\u002Dsettings', 'layerstate', null, false); }); map.on('baselayerchange', function (e) { //console.log('baselayerchange') ; //console.log(e) ; //if (e.sourceTarget._popup === null) { sendData2('baselayer=' + e.layer.options.alias, 'https\u003A\/\/ille\u002Det\u002Dvilaine.sysma.io\/update\u002Dbaselayer', 'layerstate', null); //} }); map.on('overlayremove', function (e) { //console.log('overlayremove') ; sendData2('action=remove&otherbaselayer=' + e.layer.options.alias, 'https\u003A\/\/ille\u002Det\u002Dvilaine.sysma.io\/update\u002Dother\u002Dbaselayer', 'layerstate', null); }); map.on('overlayadd', function (e) { //console.log('overlayadd') ; sendData2('action=add&otherbaselayer=' + e.layer.options.alias, 'https\u003A\/\/ille\u002Det\u002Dvilaine.sysma.io\/update\u002Dother\u002Dbaselayer', 'layerstate', null); }); // OnClick map events var groupCad = L.layerGroup(); groupCad.addTo(map); var groupRpg = L.layerGroup(); groupRpg.addTo(map); var groupCoord = L.layerGroup(); groupCoord.addTo(map); var selectedLayer = L.layerGroup(); selectedLayer.addTo(map); var selectedItems = [] ; map.on('dblclick', function (e) { }) ; map.on('click', function (e) { //console.log('click') ; // selected feature style reset selectedLayer.remove() ; selectedLayer.clearLayers() ; selectedItems = [] ; groupCad.clearLayers(); // // map click coordinates infos if (!$('#iconCoord').hasClass('text-inactive') && $('#iconCoord').length>0) { groupCoord.clearLayers(); var markerCoord = L.marker(e.latlng); groupCoord.addLayer(markerCoord); sendData('mouse=' + e.latlng, 'https\u003A\/\/ille\u002Det\u002Dvilaine.sysma.io\/coords', 'objet', event, true); $('#infos').hide(150); $('#objet').show(150); } // // map click cadastre infos if (!$('#iconCad').hasClass('text-inactive') && $('#iconCad').length>0) { $('#infos').hide(150); $('#objet').show(150); openClose('rightColumn', '60%', 'map', '40%'); sendData('mouse=' + e.latlng, 'https\u003A\/\/ille\u002Det\u002Dvilaine.sysma.io\/infos\u002Dcadastre', 'objet', null); } // map click RPG infos if (!$('#iconRpg').hasClass('text-inactive') && $('#iconRpg').length>0) { $('#infos').hide(150); $('#objet').show(150); openClose('rightColumn', '60%', 'map', '40%'); sendData('mouse=' + e.latlng, 'https\u003A\/\/ille\u002Det\u002Dvilaine.sysma.io\/infos\u002Drpg', 'objet', null); } }); sendData(null, 'https\u003A\/\/ille\u002Det\u002Dvilaine.sysma.io\/layermanager', 'infos', null);