(function ($, OC) {
'use strict';
var gpxedit = {
map: {},
baseLayers: null,
drawControl: null,
id: 0,
// indexed by gpxedit_id
layersData: {}
};
var symbolSelectClasses = {
'marker': 'marker-select',
'Dot, White': 'dot-select',
'Pin, Blue': 'pin-blue-select',
'Pin, Green': 'pin-green-select',
'Pin, Red': 'pin-red-select',
'Flag, Green': 'flag-green-select',
'Flag, Red': 'flag-red-select',
'Flag, Blue': 'flag-blue-select',
'Block, Blue': 'block-blue-select',
'Block, Green': 'block-green-select',
'Block, Red': 'block-red-select',
'Blue Diamond': 'diamond-blue-select',
'Green Diamond': 'diamond-green-select',
'Red Diamond': 'diamond-red-select',
'Residence': 'residence-select',
'Drinking Water': 'drinking-water-select',
'Trail Head': 'hike-select',
'Bike Trail': 'bike-trail-select',
'Campground': 'campground-select',
'Bar': 'bar-select',
'Skull and Crossbones': 'skullcross-select',
'Geocache': 'geocache-select',
'Geocache Found': 'geocache-open-select',
'Medical Facility': 'medical-select',
'Contact, Alien': 'contact-alien-select',
'Contact, Big Ears': 'contact-bigears-select',
'Contact, Female3': 'contact-female3-select',
'Contact, Cat': 'contact-cat-select',
'Contact, Dog': 'contact-dog-select',
}
var symbolIcons = {
'marker': L.divIcon({
className: 'leaflet-marker-blue',
iconAnchor: [12, 41]
}),
'Dot, White': L.divIcon({
iconSize:L.point(7,7),
}),
'Pin, Blue': L.divIcon({
className: 'pin-blue',
iconAnchor: [5, 30]
}),
'Pin, Green': L.divIcon({
className: 'pin-green',
iconAnchor: [5, 30]
}),
'Pin, Red': L.divIcon({
className: 'pin-red',
iconAnchor: [5, 30]
}),
'Flag, Green': L.divIcon({
className: 'flag-green',
iconAnchor: [1, 25]
}),
'Flag, Red': L.divIcon({
className: 'flag-red',
iconAnchor: [1, 25]
}),
'Flag, Blue': L.divIcon({
className: 'flag-blue',
iconAnchor: [1, 25]
}),
'Block, Blue': L.divIcon({
className: 'block-blue',
iconAnchor: [8, 8]
}),
'Block, Green': L.divIcon({
className: 'block-green',
iconAnchor: [8, 8]
}),
'Block, Red': L.divIcon({
className: 'block-red',
iconAnchor: [8, 8]
}),
'Blue Diamond': L.divIcon({
className: 'diamond-blue',
iconAnchor: [9, 9]
}),
'Green Diamond': L.divIcon({
className: 'diamond-green',
iconAnchor: [9, 9]
}),
'Red Diamond': L.divIcon({
className: 'diamond-red',
iconAnchor: [9, 9]
}),
'Residence': L.divIcon({
className: 'residence',
iconAnchor: [12, 12]
}),
'Drinking Water': L.divIcon({
className: 'drinking-water',
iconAnchor: [12, 12]
}),
'Trail Head': L.divIcon({
className: 'hike',
iconAnchor: [12, 12]
}),
'Bike Trail': L.divIcon({
className: 'bike-trail',
iconAnchor: [12, 12]
}),
'Campground': L.divIcon({
className: 'campground',
iconAnchor: [12, 12]
}),
'Bar': L.divIcon({
className: 'bar',
iconAnchor: [10, 12]
}),
'Skull and Crossbones': L.divIcon({
className: 'skullcross',
iconAnchor: [12, 12]
}),
'Geocache': L.divIcon({
className: 'geocache',
iconAnchor: [11, 10]
}),
'Geocache Found': L.divIcon({
className: 'geocache-open',
iconAnchor: [11, 10]
}),
'Medical Facility': L.divIcon({
className: 'medical',
iconAnchor: [13, 11]
}),
'Contact, Alien': L.divIcon({
className: 'contact-alien',
iconAnchor: [12, 12]
}),
'Contact, Big Ears': L.divIcon({
className: 'contact-bigears',
iconAnchor: [12, 12]
}),
'Contact, Female3': L.divIcon({
className: 'contact-female3',
iconAnchor: [12, 12]
}),
'Contact, Cat': L.divIcon({
className: 'contact-cat',
iconAnchor: [12, 12]
}),
'Contact, Dog': L.divIcon({
className: 'contact-dog',
iconAnchor: [12, 12]
}),
}
var hoverStyle = {
weight: 12,
opacity: 0.7,
color: 'black'
};
var defaultStyle = {
opacity: 0.9,
color: '#f357a1',
weight: 7
};
function endsWith(str, suffix) {
return str.indexOf(suffix, str.length - suffix.length) !== -1;
}
function load_map() {
// change meta to send referrer
// usefull for IGN tiles authentication !
$('meta[name=referrer]').attr('content', 'origin');
var layer = getUrlParameter('layer');
console.log('layer '+layer);
var default_layer = 'OpenStreetMap';
if (typeof layer !== 'undefined'){
default_layer = decodeURI(layer);
}
// get url from key and layer type
function geopUrl (key, layer, format)
{ return 'http://wxs.ign.fr/'+ key + '/wmts?LAYER=' + layer
+'&EXCEPTIONS=text/xml&FORMAT='+(format?format:'image/jpeg')
+'&SERVICE=WMTS&VERSION=1.0.0&REQUEST=GetTile&STYLE=normal'
+'&TILEMATRIXSET=PM&TILEMATRIX={z}&TILECOL={x}&TILEROW={y}' ;
}
// change it if you deploy GPXEDIT
var API_KEY = 'ljthe66m795pr2v2g8p7faxt';
var ign = new L.tileLayer ( geopUrl(API_KEY,'GEOGRAPHICALGRIDSYSTEMS.MAPS'),
{ attribution:'© IGN-France',
maxZoom:18
});
var osmUrl = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
var osmAttribution = 'Map data © 2013 OpenStreetMap contributors';
var osm = new L.TileLayer(osmUrl, {maxZoom: 18, attribution: osmAttribution});
var osmfrUrl = 'http://{s}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png';
var osmfr = new L.TileLayer(osmfrUrl,
{maxZoom: 20, attribution: osmAttribution});
var osmfr2 = new L.TileLayer(osmfrUrl,
{minZoom: 0, maxZoom: 13, attribution: osmAttribution});
var openmapsurferUrl = 'http://openmapsurfer.uni-hd.de/tiles/roads/'+
'x={x}&y={y}&z={z}';
var openmapsurferAttribution = 'Imagery from GIScience Research Group @ University of Heidelberg — '+
'Map data © '+
'OpenStreetMap';
var openmapsurfer = new L.TileLayer(openmapsurferUrl,
{maxZoom: 18, attribution: openmapsurferAttribution});
var transportUrl = 'http://a.tile2.opencyclemap.org/transport/{z}/{x}/{y}.'+
'png';
var transport = new L.TileLayer(transportUrl,
{maxZoom: 18, attribution: osmAttribution});
var pisteUrl = 'http://tiles.openpistemap.org/nocontours/{z}/{x}/{y}.png';
var piste = new L.TileLayer(pisteUrl,
{maxZoom: 18, attribution: osmAttribution});
var hikebikeUrl = 'http://toolserver.org/tiles/hikebike/{z}/{x}/{y}.png';
var hikebike = new L.TileLayer(hikebikeUrl,
{maxZoom: 18, attribution: osmAttribution});
var osmCycleUrl = 'http://{s}.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png';
var osmCycleAttrib = '© '+
'OpenCycleMap, © '+
'OpenStreetMap';
var osmCycle = new L.TileLayer(osmCycleUrl,
{maxZoom: 18, attribution: osmCycleAttrib});
var darkUrl = 'http://a.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png';
var darkAttrib = '© Map tiles by CartoDB, under CC BY 3.0. Data by'+
' OpenStreetMap, under ODbL.';
var dark = new L.TileLayer(darkUrl, {maxZoom: 18, attribution: darkAttrib});
var esriTopoUrl = 'https://server.arcgisonline.com/ArcGIS/rest/services/World'+
'_Topo_Map/MapServer/tile/{z}/{y}/{x}';
var esriTopoAttrib = 'Tiles © Esri — Esri, DeLorme, NAVTEQ, '+
'TomTom, Intermap, iPC, USGS, FAO, NPS, NRCAN, GeoBase, Kadaster NL, Ord'+
'nance Survey, Esri Japan, METI, Esri China (Hong Kong), and the GIS User'+
' Community';
var esriTopo = new L.TileLayer(esriTopoUrl,
{maxZoom: 18, attribution: esriTopoAttrib});
var esriAerialUrl = 'https://server.arcgisonline.com/ArcGIS/rest/services'+
'/World_Imagery/MapServer/tile/{z}/{y}/{x}';
var esriAerialAttrib = 'Tiles © Esri — Source: Esri, i-cubed, '+
'USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the'+
' GIS User Community';
var esriAerial = new L.TileLayer(esriAerialUrl,
{maxZoom: 18, attribution: esriAerialAttrib});
var tonerUrl = 'http://{s}.tile.stamen.com/toner/{z}/{x}/{y}.jpg';
var stamenAttribution = 'Leaflet | © Map tiles by Stamen Design, under CC BY 3.0, Data by OpenSt'+
'reetMap, under CC BY SA.';
var toner = new L.TileLayer(tonerUrl,
{maxZoom: 18, attribution: stamenAttribution});
var watercolorUrl = 'http://{s}.tile.stamen.com/watercolor/{z}/{x}/{y}.jpg';
var watercolor = new L.TileLayer(watercolorUrl,
{maxZoom: 18, attribution: stamenAttribution});
var routeUrl = 'http://{s}.tile.openstreetmap.fr/route500/{z}/{x}/{y}.png';
var routeAttrib = '©, Tiles © O'+
'penStreetMap France';
var route = new L.TileLayer(routeUrl,
{minZoom: 1, maxZoom: 20, attribution: routeAttrib});
var baseLayers = {
'OpenStreetMap': osm,
'OpenCycleMap': osmCycle,
'IGN France': ign,
'OpenMapSurfer Roads': openmapsurfer,
'Hike & bike': hikebike,
'OSM Transport': transport,
'ESRI Aerial': esriAerial,
'ESRI Topo with relief': esriTopo,
'Dark' : dark,
'Toner' : toner,
'Watercolor' : watercolor,
'OpenStreetMap France': osmfr
};
// add custom layers
$('#tileserverlist li').each(function(){
var sname = $(this).attr('name');
var surl = $(this).attr('title');
baseLayers[sname] = new L.TileLayer(surl,
{maxZoom: 18, attribution: 'custom tile server'});
});
gpxedit.baseLayers = baseLayers;
var baseOverlays = {
'OsmFr Route500': route,
'OpenPisteMap Relief':
L.tileLayer('http://tiles2.openpistemap.org/landshaded/{z}/{x}/{y}.png',
{
attribution: '©, Tiles © OpenStreetMap France',
minZoom: 1,
maxZoom: 15
}
),
'OpenPisteMap pistes' : piste
};
var layerlist = [];
gpxedit.map = new L.Map('map', {
zoomControl: true,
layers: layerlist,
});
L.control.scale({metric: true, imperial: true, position:'topleft'})
.addTo(gpxedit.map);
L.control.mousePosition().addTo(gpxedit.map);
gpxedit.searchControl = L.Control.geocoder({position:'topleft'});
gpxedit.searchControl.addTo(gpxedit.map);
gpxedit.locateControl = L.control.locate({follow:true});
gpxedit.locateControl.addTo(gpxedit.map);
L.Control.measureControl().addTo(gpxedit.map);
L.control.sidebar('sidebar').addTo(gpxedit.map);
gpxedit.map.setView(new L.LatLng(27, 5), 3);
if (! baseLayers.hasOwnProperty(default_layer)){
default_layer = 'OpenStreetMap';
}
gpxedit.map.addLayer(baseLayers[default_layer]);
gpxedit.activeLayers = L.control.activeLayers(baseLayers, baseOverlays);
gpxedit.activeLayers.addTo(gpxedit.map);
gpxedit.minimapControl = new L.Control.MiniMap(
osmfr2,
{ toggleDisplay: true, position:'bottomright' }
).addTo(gpxedit.map);
gpxedit.minimapControl._toggleDisplayButtonClicked();
gpxedit.editableLayers = new L.FeatureGroup();
gpxedit.map.addLayer(gpxedit.editableLayers);
var options = {
position: 'bottomleft',
draw: {
polyline: {
shapeOptions: {
color: '#f357a1',
weight: 7
}
},
polygon:false,
circle: false,
rectangle:false,
marker: {
icon: symbolIcons['marker']
}
},
edit: {
featureGroup: gpxedit.editableLayers, //REQUIRED!!
}
};
L.drawLocal.draw.toolbar.buttons.polyline = t('gpxedit','Draw a track');
L.drawLocal.draw.toolbar.buttons.marker = t('gpxedit','Add a waypoint');
L.drawLocal.edit.toolbar.buttons.edit = t('gpxedit','Edit');
L.drawLocal.edit.toolbar.buttons.editDisabled = t('gpxedit','Nothing to edit');
L.drawLocal.edit.toolbar.buttons.remove = t('gpxedit','Delete');
L.drawLocal.edit.toolbar.buttons.removeDisabled = t('gpxedit','Nothing to delete');
L.drawLocal.edit.toolbar.actions.save.title = t('gpxedit','Validate changes');
L.drawLocal.edit.toolbar.actions.save.text = t('gpxedit','Ok');
L.drawLocal.edit.toolbar.actions.cancel.title = t('gpxedit','Discard all changes');
L.drawLocal.edit.toolbar.actions.cancel.text = t('gpxedit','Cancel');
L.drawLocal.edit.handlers.edit.tooltip.text = t('gpxedit','Drag to move elements,
click to remove a point');
L.drawLocal.edit.handlers.edit.tooltip.subtext = t('gpxedit','Click cancel to undo changes');
L.drawLocal.edit.handlers.remove.tooltip.text = t('gpxedit','Click on an element to delete it');
L.drawLocal.draw.handlers.marker.tooltip.start = t('gpxedit','Click map to add waypoint');
L.drawLocal.draw.handlers.polyline.tooltip.start = t('gpxedit','Click to start drawing track');
L.drawLocal.draw.handlers.polyline.tooltip.cont = t('gpxedit','Click to continue drawing track');
L.drawLocal.draw.handlers.polyline.tooltip.end = t('gpxedit','Click last point to finish track');
L.drawLocal.draw.toolbar.actions.text = t('gpxedit','Cancel');
L.drawLocal.draw.toolbar.actions.title = t('gpxedit','Cancel drawing');
L.drawLocal.draw.toolbar.finish.text = t('gpxedit','Finish');
L.drawLocal.draw.toolbar.finish.title = t('gpxedit','Finish drawing');
L.drawLocal.draw.toolbar.undo.text = t('gpxedit','Delete last point');
L.drawLocal.draw.toolbar.undo.title = t('gpxedit','Delete last point drawn');
var drawControl = new L.Control.Draw(options);
gpxedit.drawControl = drawControl;
gpxedit.map.addControl(drawControl);
// when something is created, we generate popup content
// and initialize layer data
gpxedit.map.on(L.Draw.Event.CREATED, function (e) {
onCreated(e.layerType, e.layer);
});
// not used for the moment
gpxedit.map.on('draw:edited', function (e) {
var layers = e.layers;
layers.eachLayer(function (layer) {
});
});
// remove data associated with the deleted layer
gpxedit.map.on('draw:deleted', function (e) {
var layers = e.layers;
layers.eachLayer(function (layer) {
delete gpxedit.layersData[layer.gpxedit_id];
});
});
// load data into popup when it opens
// this is needed because popup content is created each time we open one
// so, the content is lost when it's closed
gpxedit.map.on('popupopen', function(e){
var id = e.popup._source.gpxedit_id;
//var id = parseInt(e.popup.getContent().match(/layerid="(\d+)"/)[1]);
var buttonParent = $('button.popupOkButton[layerid='+id+']').parent();
buttonParent.find('input.layerName').val(gpxedit.layersData[id].name);
buttonParent.find('textarea.layerDesc').val(gpxedit.layersData[id].description);
buttonParent.find('textarea.layerCmt').val(gpxedit.layersData[id].comment);
if (gpxedit.layersData[id].layer.type === 'marker'){
buttonParent.find('select[role=symbol]').val(gpxedit.layersData[id].symbol);
buttonParent.find('select[role=symbol]').change();
}
});
}
// called when something is drawn by hand or when a gpx is loaded
// it generates the popup content and initializes the layer's data
// it returns the layer in case we want to set the layer's data manually (when loading a gpx)
function onCreated(type, layer){
var popupTitle;
var layerType;
if (type === 'polyline' || type === 'track'){
popupTitle = t('gpxedit', 'Track');
layerType = 'track';
}
else if (type === 'route') {
popupTitle = t('gpxedit', 'Route');
layerType = 'route';
}
else if (type === 'marker') {
popupTitle = t('gpxedit', 'Waypoint');
layerType = 'marker';
}
var popupTxt = '
'+t('gpxedit', 'Name')+' | |
'+t('gpxedit', 'Description')+' | |
'+t('gpxedit', 'Comment')+' | |
'+t('gpxedit', 'Symbol')+' |