https://gitlab.com/eneiluj/gpxedit-oc/wikis/userdoc
diff --git a/controller/pagecontroller.php b/controller/pagecontroller.php
index 71f5ec5..faecb64 100644
--- a/controller/pagecontroller.php
+++ b/controller/pagecontroller.php
@@ -138,7 +138,8 @@ class PageController extends Controller {
$userFolder = \OC::$server->getUserFolder();
$userfolder_path = $userFolder->getPath();
- $tss = $this->getUserTileServers();
+ $tss = $this->getUserTileServers('tile');
+ $oss = $this->getUserTileServers('overlay');
// extra symbols
$dataDirPath = $this->config->getSystemValue('datadirectory').'/gpxedit';
@@ -152,9 +153,12 @@ class PageController extends Controller {
// PARAMS to view
+ require_once('tileservers.php');
$params = [
'username'=>$this->userId,
+ 'basetileservers'=>$baseTileServers,
'tileservers'=>$tss,
+ 'overlayservers'=>$oss,
'extrasymbols'=>$extraSymbolList,
'gpxedit_version'=>$this->appVersion
];
@@ -368,10 +372,18 @@ class PageController extends Controller {
return $response;
}
- private function getUserTileServers(){
+ /*
+ * quote and choose string escape function depending on database used
+ */
+ private function db_quote_escape_string($str){
+ return $this->dbconnection->quote($str);
+ }
+
+ private function getUserTileServers($type){
// custom tile servers management
$sqlts = 'SELECT servername, url FROM *PREFIX*gpxedit_tile_servers ';
- $sqlts .= 'WHERE '.$this->dbdblquotes.'user'.$this->dbdblquotes.'=\''.$this->userId.'\';';
+ $sqlts .= 'WHERE '.$this->dbdblquotes.'user'.$this->dbdblquotes.'='.$this->db_quote_escape_string($this->userId).' ';
+ $sqlts .= 'AND type='.$this->db_quote_escape_string($type).';';
$req = $this->dbconnection->prepare($sqlts);
$req->execute();
$tss = Array();
diff --git a/controller/tileservers.php b/controller/tileservers.php
new file mode 100644
index 0000000..70f42cc
--- /dev/null
+++ b/controller/tileservers.php
@@ -0,0 +1,130 @@
+ '',
+ // 'type' => 'tile|overlay',
+ // 'url' => '',
+ // 'attribution' => '',
+ // 'minzoom' => '',
+ // 'maxzoom' => ''
+ //),
+ Array(
+ 'name' => 'OpenStreetMap',
+ 'type' => 'tile',
+ 'url' => 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
+ 'attribution' => 'Map data © 2013 OpenStreetMap contributors',
+ 'minzoom' => '1',
+ 'maxzoom' => '18'
+ ),
+ Array(
+ 'name' => 'OpenCycleMap',
+ 'type' => 'tile',
+ 'url' => 'http://{s}.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png',
+ 'attribution' => '© OpenCycleMap, © OpenStreetMap',
+ 'minzoom' => '1',
+ 'maxzoom' => '18'
+ ),
+ Array(
+ 'name' => 'OpenStreetMap Transport',
+ 'type' => 'tile',
+ 'url' => 'http://a.tile2.opencyclemap.org/transport/{z}/{x}/{y}.png',
+ 'attribution' => 'Map data © 2013 OpenStreetMap contributors',
+ 'minzoom' => '1',
+ 'maxzoom' => '18'
+ ),
+ Array(
+ 'name' => 'ESRI Aerial',
+ 'type' => 'tile',
+ 'url' => 'https://server.arcgisonline.com/ArcGIS/rest/services' .
+ '/World_Imagery/MapServer/tile/{z}/{y}/{x}',
+ 'attribution' => 'Tiles © Esri — Source: Esri, i-cubed, ' .
+ 'USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the' .
+ ' GIS User Community',
+ 'minzoom' => '1',
+ 'maxzoom' => '18'
+ ),
+ Array(
+ 'name' => 'ESRI Topo with relief',
+ 'type' => 'tile',
+ 'url' => 'https://server.arcgisonline.com/ArcGIS/rest/services/World' .
+ '_Topo_Map/MapServer/tile/{z}/{y}/{x}',
+ 'attribution' => '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',
+ 'minzoom' => '1',
+ 'maxzoom' => '18'
+ ),
+ Array(
+ 'name' => 'Hike & bike',
+ 'type' => 'tile',
+ 'url' => 'http://a.tiles.wmflabs.org/hikebike/{z}/{x}/{y}.png',
+ 'attribution' => 'Map data © 2013 OpenStreetMap contributors',
+ 'minzoom' => '1',
+ 'maxzoom' => '18'
+ ),
+ Array(
+ 'name' => 'OpenStreetMap France',
+ 'type' => 'tile',
+ 'url' => 'https://{s}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png',
+ 'attribution' => 'Map data © 2013 OpenStreetMap contributors',
+ 'minzoom' => '',
+ 'maxzoom' => ''
+ ),
+ Array(
+ 'name' => 'IGN France',
+ 'type' => 'tile',
+ 'url' => 'http://wxs.ign.fr/ljthe66m795pr2v2g8p7faxt/wmts?LAYER=GEOGRAPHICALGRIDSYSTEMS.MAPS' .
+ '&EXCEPTIONS=text/xml&FORMAT=image/jpeg' .
+ '&SERVICE=WMTS&VERSION=1.0.0&REQUEST=GetTile&STYLE=normal' +
+ '&TILEMATRIXSET=PM&TILEMATRIX={z}&TILECOL={x}&TILEROW={y}',
+ 'attribution' => '© IGN-France',
+ 'minzoom' => '1',
+ 'maxzoom' => '18'
+ ),
+ Array(
+ 'name' => 'Dark',
+ 'type' => 'tile',
+ 'url' => 'http://a.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png',
+ 'attribution' => '© Map tiles by CartoDB, under CC BY 3.0. Data by' .
+ ' OpenStreetMap, under ODbL.',
+ 'minzoom' => '1',
+ 'maxzoom' => '18'
+ ),
+ Array(
+ 'name' => 'WaterColor',
+ 'type' => 'tile',
+ 'url' => 'http://{s}.tile.stamen.com/watercolor/{z}/{x}/{y}.jpg',
+ 'attribution' => 'Leaflet | © Map tiles by Stamen Design, under CC BY 3.0, Data by OpenSt' .
+ 'reetMap, under CC BY SA.',
+ 'minzoom' => '1',
+ 'maxzoom' => '18'
+ ),
+ Array(
+ 'name' => 'Toner',
+ 'type' => 'tile|overlay',
+ 'url' => 'http://{s}.tile.stamen.com/toner/{z}/{x}/{y}.jpg',
+ 'attribution' => 'Leaflet | © Map tiles by Stamen Design, under CC BY 3.0, Data by OpenSt' .
+ 'reetMap, under CC BY SA.',
+ 'minzoom' => '1',
+ 'maxzoom' => '18'
+ ),
+ Array(
+ 'name' => 'OsmFr Route500',
+ 'type' => 'overlay',
+ 'url' => 'http://{s}.tile.openstreetmap.fr/route500/{z}/{x}/{y}.png',
+ 'attribution' => '©, Tiles © OpenStreetMap France',
+ 'minzoom' => '1',
+ 'maxzoom' => '20'
+ ),
+];
+?>
diff --git a/controller/utilscontroller.php b/controller/utilscontroller.php
index a897ac5..2c9de3e 100644
--- a/controller/utilscontroller.php
+++ b/controller/utilscontroller.php
@@ -203,11 +203,11 @@ class UtilsController extends Controller {
* Add one tile server to the DB for current user
* @NoAdminRequired
*/
- public function addTileServer($servername, $serverurl) {
+ public function addTileServer($servername, $serverurl, $type) {
// first we check it does not already exist
$sqlts = 'SELECT servername FROM *PREFIX*gpxedit_tile_servers ';
$sqlts .= 'WHERE '.$this->dbdblquotes.'user'.$this->dbdblquotes.'=\''.$this->userId.'\' ';
- $sqlts .= 'AND servername=\''.$servername.'\' ';
+ $sqlts .= 'AND servername='.$this->db_quote_escape_string($servername).' AND type='.$this->db_quote_escape_string($type).' ';
$req = $this->dbconnection->prepare($sqlts);
$req->execute();
$ts = null;
@@ -220,10 +220,11 @@ class UtilsController extends Controller {
// then if not, we insert it
if ($ts === null){
$sql = 'INSERT INTO *PREFIX*gpxedit_tile_servers';
- $sql .= ' ('.$this->dbdblquotes.'user'.$this->dbdblquotes.', servername, url) ';
+ $sql .= ' ('.$this->dbdblquotes.'user'.$this->dbdblquotes.', type, servername, url) ';
$sql .= 'VALUES (\''.$this->userId.'\',';
- $sql .= '\''.$servername.'\',';
- $sql .= '\''.$serverurl.'\');';
+ $sql .= ''.$this->db_quote_escape_string($type).',';
+ $sql .= ''.$this->db_quote_escape_string($servername).',';
+ $sql .= ''.$this->db_quote_escape_string($serverurl).');';
$req = $this->dbconnection->prepare($sql);
$req->execute();
$req->closeCursor();
@@ -250,11 +251,10 @@ class UtilsController extends Controller {
* Delete one tile server entry from DB for current user
* @NoAdminRequired
*/
- public function deleteTileServer($servername) {
+ public function deleteTileServer($servername, $type) {
$sqldel = 'DELETE FROM *PREFIX*gpxedit_tile_servers ';
- $sqldel .= 'WHERE '.$this->dbdblquotes.'user'.$this->dbdblquotes.'=\''.$this->userId.'\' AND servername=\'';
- $sqldel .= $servername.'\';';
- //$sqldel .= 'WHERE user=\''.$this->userId.'\';';
+ $sqldel .= 'WHERE '.$this->dbdblquotes.'user'.$this->dbdblquotes.'='.$this->db_quote_escape_string($this->userId).' AND servername=';
+ $sqldel .= $this->db_quote_escape_string($servername).' AND type='.$this->db_quote_escape_string($type).';';
$req = $this->dbconnection->prepare($sqldel);
$req->execute();
$req->closeCursor();
@@ -328,7 +328,7 @@ class UtilsController extends Controller {
*/
public function getOptionsValues($optionsValues) {
$sqlov = 'SELECT jsonvalues FROM *PREFIX*gpxedit_options_values ';
- $sqlov .= 'WHERE '.$this->dbdblquotes.'user'.$this->dbdblquotes.'=\''.$this->userId.'\' ;';
+ $sqlov .= 'WHERE '.$this->dbdblquotes.'user'.$this->dbdblquotes.'='.$this->db_quote_escape_string($this->userId).' ;';
$req = $this->dbconnection->prepare($sqlov);
$req->execute();
$ov = '{}';
@@ -350,4 +350,11 @@ class UtilsController extends Controller {
return $response;
}
+ /*
+ * quote and choose string escape function depending on database used
+ */
+ private function db_quote_escape_string($str){
+ return $this->dbconnection->quote($str);
+ }
+
}
diff --git a/css/gpxedit.css b/css/gpxedit.css
index 6dd6a2f..c2ea71e 100644
--- a/css/gpxedit.css
+++ b/css/gpxedit.css
@@ -317,7 +317,8 @@ h3 {
#clean_results ul{
list-style-type:disc;
}
-#tileserveradd, #tileserveradd input{
+#tileserveradd, #tileserveradd input,
+#overlayserveradd, #overlayserveradd input{
width:100%;
}
diff --git a/js/gpxedit.js b/js/gpxedit.js
index 3a45db8..cdd4c94 100644
--- a/js/gpxedit.js
+++ b/js/gpxedit.js
@@ -192,116 +192,23 @@
default_layer = decodeURIComponent(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 osmfr2 = new L.TileLayer('https://{s}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png', {
+ minZoom: 0,
+ maxZoom: 13,
+ attribution: 'Map data © 2013 OpenStreetMap contributors'
+ });
- 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 baseLayers = {};
- 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 base layers
+ $('#basetileservers li[type=tile]').each(function() {
+ var sname = $(this).attr('name');
+ var surl = $(this).attr('url');
+ var minz = parseInt($(this).attr('minzoom'));
+ var maxz = parseInt($(this).attr('maxzoom'));
+ var sattrib = $(this).attr('attribution');
+ baseLayers[sname] = new L.TileLayer(surl, {minZoom: minz, maxZoom: maxz, attribution: sattrib});
+ });
// add custom layers
$('#tileserverlist li').each(function() {
var sname = $(this).attr('name');
@@ -310,25 +217,29 @@
{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 = [];
+ var baseOverlays = {};
+
+ // add base overlays
+ $('#basetileservers li[type=overlay]').each(function() {
+ var sname = $(this).attr('name');
+ var surl = $(this).attr('url');
+ var minz = parseInt($(this).attr('minzoom'));
+ var maxz = parseInt($(this).attr('maxzoom'));
+ var sattrib = $(this).attr('attribution');
+ baseOverlays[sname] = new L.TileLayer(surl, {minZoom: minz, maxZoom: maxz, attribution: sattrib});
+ });
+ // add custom overlays
+ $('#overlayserverlist li').each(function() {
+ var sname = $(this).attr('name');
+ var surl = $(this).attr('title');
+ baseOverlays[sname] = new L.TileLayer(surl,
+ {maxZoom: 18, attribution: 'custom overlay server'});
+ });
+ gpxedit.overlayLayers = baseOverlays;
gpxedit.map = new L.Map('map', {
zoomControl: true,
- layers: layerlist,
});
L.control.scale({metric: true, imperial: true, position: 'topleft'})
@@ -347,6 +258,7 @@
if (! baseLayers.hasOwnProperty(default_layer)) {
default_layer = 'OpenStreetMap';
}
+console.log(baseLayers);
gpxedit.map.addLayer(baseLayers[default_layer]);
gpxedit.activeLayers = L.control.activeLayers(baseLayers, baseOverlays);
@@ -1128,10 +1040,11 @@
});
}
- function deleteTileServer(li) {
+ function deleteTileServer(li, type) {
var sname = li.attr('name');
var req = {
- servername: sname
+ servername: sname,
+ type: type
};
var url = OC.generateUrl('/apps/gpxedit/deleteTileServer');
$.ajax({
@@ -1140,54 +1053,54 @@
data: req,
async: true
}).done(function (response) {
- //alert(response.done);
if (response.done) {
li.fadeOut('slow', function() {
li.remove();
});
- var activeLayerName = gpxedit.activeLayers.getActiveBaseLayer().name;
- // if we delete the active layer, first select another
- if (activeLayerName === sname) {
- $('input.leaflet-control-layers-selector').first().click();
+ if (type === 'tile') {
+ var activeLayerName = gpxedit.activeLayers.getActiveBaseLayer().name;
+ // if we delete the active layer, first select another
+ if (activeLayerName === sname) {
+ $('input.leaflet-control-layers-selector').first().click();
+ }
+ gpxedit.activeLayers.removeLayer(gpxedit.baseLayers[sname]);
+ delete gpxedit.baseLayers[sname];
}
- gpxedit.activeLayers.removeLayer(gpxedit.baseLayers[sname]);
- delete gpxedit.baseLayers[sname];
- OC.Notification.showTemporary(
- t('gpxedit', 'Tile server "{ts}" has been deleted', {ts: sname})
- );
+ else {
+ gpxedit.activeLayers.removeLayer(gpxedit.overlayLayers[sname]);
+ delete gpxedit.overlayLayers[sname];
+ }
+ OC.Notification.showTemporary(t('gpxedit', 'Tile server "{ts}" has been deleted', {ts: sname}));
}
else{
- OC.Notification.showTemporary(
- t('gpxedit', 'Failure on tile server "{ts}" deletion', {ts: sname})
- );
+ OC.Notification.showTemporary(t('gpxedit', 'Failed to delete tile server "{ts}"', {ts: sname}));
}
}).always(function() {
}).fail(function() {
- OC.Notification.showTemporary(
- t('gpxedit', 'Failure on tile server "{ts}" deletion', {ts: sname})
- );
+ OC.Notification.showTemporary(t('gpxedit', 'Failed to delete tile server "{ts}"', {ts: sname}));
});
}
- function addTileServer() {
- var sname = $('#tileservername').val();
- var surl = $('#tileserverurl').val();
+ function addTileServer(type) {
+ var sname = $('#'+type+'servername').val();
+ var surl = $('#'+type+'serverurl').val();
if (sname === '' || surl === '') {
OC.dialogs.alert(t('gpxedit', 'Server name or server url should not be empty'),
t('gpxedit', 'Impossible to add tile server'));
return;
}
- if ($('#tileserverlist ul li[name="' + sname + '"]').length > 0) {
+ if ($('#'+type+'serverlist ul li[name="' + sname + '"]').length > 0) {
OC.dialogs.alert(t('gpxedit', 'A server with this name already exists'),
t('gpxedit', 'Impossible to add tile server'));
return;
}
- $('#tileservername').val('');
- $('#tileserverurl').val('');
+ $('#'+type+'servername').val('');
+ $('#'+type+'serverurl').val('');
var req = {
servername: sname,
- serverurl: surl
+ serverurl: surl,
+ type: type
};
var url = OC.generateUrl('/apps/gpxedit/addTileServer');
$.ajax({
@@ -1196,41 +1109,39 @@
data: req,
async: true
}).done(function (response) {
- //alert(response.done);
if (response.done) {
- $('#tileserverlist ul').prepend(
- '' + sname + ' ';
}
echo ''."\n";
+echo '';
+foreach($_['basetileservers'] as $ts){
+ echo '';
+}
+echo '
'."\n";
?>
@@ -130,6 +147,36 @@ if (count($_['tileservers']) > 0){
echo '';
}
}
+?>
+
+
+
+ t('Custom overlay servers')); ?>
+
+ t('Server name (for example \'my custom server\')')); ?> :
+
+ t('Server url (\'http://overlay.server.org/cycle/{z}/{x}/{y}.png\')')); ?> :
+
+ t('Add')); ?>
+
+
+
+
t('Your servers')); ?>
+
+ 0){
+ foreach($_['overlayservers'] as $name=>$url){
+ echo '- ';
+ p($name);
+ echo ' ';
+ p($l->t('Delete'));
+ echo '
';
+ }
+}
?>