Initial commit - Typo3 11.5.41
@@ -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.
|
||||
@@ -0,0 +1,78 @@
|
||||
Leaflet.Control.FullScreen
|
||||
============
|
||||
|
||||
What ?
|
||||
------
|
||||
|
||||
Simple plugin for Leaflet that adds fullscreen button to your maps.
|
||||
|
||||
Inspired by http://elidupuis.github.com/leaflet.zoomfs/
|
||||
|
||||
Use the native javascript fullscreen API with help of https://github.com/sindresorhus/screenfull.js
|
||||
|
||||
Icons from [Font Awesome v5.15.4](https://github.com/FortAwesome/Font-Awesome/releases/tag/5.15.4): [Creative Commons Attribution 4.0](https://fontawesome.com/license/free)
|
||||
|
||||
Released under the MIT License http://opensource.org/licenses/mit-license.php
|
||||
|
||||
How ?
|
||||
------
|
||||
|
||||
Include Control.FullScreen.js and Control.FullScreen.css in your page:
|
||||
|
||||
``` html
|
||||
<link rel="stylesheet" href="Control.FullScreen.css" />
|
||||
<script src="Control.FullScreen.js"></script>
|
||||
```
|
||||
|
||||
Add the fullscreen control to the map:
|
||||
|
||||
``` js
|
||||
var map = new L.Map('map', {
|
||||
fullscreenControl: true,
|
||||
fullscreenControlOptions: {
|
||||
position: 'topleft'
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
If your map has a zoomControl the fullscreen button will be added at the bottom of this one.
|
||||
|
||||
If your map doesn't have a zoomControl the fullscreen button will be added to topleft corner of the map (same as the zoomControl).
|
||||
|
||||
If you want to use the plugin on a map embedded in an iframe, don't forget to set `allowfullscreen` attribute on your iframe.
|
||||
|
||||
__Events and options__:
|
||||
|
||||
``` js
|
||||
// create a fullscreen button and add it to the map
|
||||
L.control.fullscreen({
|
||||
position: 'topleft', // change the position of the button can be topleft, topright, bottomright or bottomleft, default topleft
|
||||
title: 'Show me the fullscreen !', // change the title of the button, default Full Screen
|
||||
titleCancel: 'Exit fullscreen mode', // change the title of the button when fullscreen is on, default Exit Full Screen
|
||||
content: null, // change the content of the button, can be HTML, default null
|
||||
forceSeparateButton: true, // force separate button to detach from zoom buttons, default false
|
||||
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(map);
|
||||
|
||||
// events are fired when entering or exiting fullscreen.
|
||||
map.on('enterFullscreen', function(){
|
||||
console.log('entered fullscreen');
|
||||
});
|
||||
|
||||
map.on('exitFullscreen', function(){
|
||||
console.log('exited fullscreen');
|
||||
});
|
||||
|
||||
// you can also toggle fullscreen from map object
|
||||
map.toggleFullscreen();
|
||||
```
|
||||
|
||||
Where ?
|
||||
------
|
||||
|
||||
Source code : https://github.com/brunob/leaflet.fullscreen
|
||||
|
||||
Downloads : https://github.com/brunob/leaflet.fullscreen/releases
|
||||
|
||||
Demo : https://brunob.github.io/leaflet.fullscreen/
|
||||
@@ -0,0 +1 @@
|
||||
<svg viewBox="0 0 26 52" xmlns="http://www.w3.org/2000/svg"><path d="M20.6 36.7H16a.9.9 0 0 1-.8-.8v-4.5c0-.2.2-.4.4-.4h1.4c.3 0 .5.2.5.4v3h3c.2 0 .4.2.4.5v1.4c0 .2-.2.4-.4.4zm-9.9-.8v-4.5c0-.2-.2-.4-.4-.4H8.9c-.3 0-.5.2-.5.4v3h-3c-.2 0-.4.2-.4.5v1.4c0 .2.2.4.4.4H10c.4 0 .8-.4.8-.8zm0 10.7V42c0-.4-.4-.8-.8-.8H5.4c-.2 0-.4.2-.4.4v1.4c0 .3.2.5.4.5h3v3c0 .2.2.4.5.4h1.4c.2 0 .4-.2.4-.4zm6.9 0v-3h3c.2 0 .4-.2.4-.5v-1.4c0-.2-.2-.4-.4-.4H16c-.4 0-.8.4-.8.8v4.5c0 .2.2.4.4.4h1.4c.3 0 .5-.2.5-.4zM5 10.3V5.9c0-.5.4-.9.9-.9h4.4c.2 0 .4.2.4.4V7c0 .2-.2.4-.4.4h-3v3c0 .2-.2.4-.4.4H5.4a.4.4 0 0 1-.4-.4zm10.3-4.9V7c0 .2.2.4.4.4h3v3c0 .2.2.4.4.4h1.5c.2 0 .4-.2.4-.4V5.9c0-.5-.4-.9-.9-.9h-4.4c-.2 0-.4.2-.4.4zm5.3 9.9H19c-.2 0-.4.2-.4.4v3h-3c-.2 0-.4.2-.4.4v1.5c0 .2.2.4.4.4h4.4c.5 0 .9-.4.9-.9v-4.4c0-.2-.2-.4-.4-.4zm-9.9 5.3V19c0-.2-.2-.4-.4-.4h-3v-3c0-.2-.2-.4-.4-.4H5.4c-.2 0-.4.2-.4.4v4.4c0 .5.4.9.9.9h4.4c.2 0 .4-.2.4-.4z" fill="currentColor"/></svg>
|
||||
|
After Width: | Height: | Size: 945 B |
@@ -0,0 +1,47 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset='utf-8'>
|
||||
<title>Leaflet.Control.FullScreen Demo</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@latest/dist/leaflet.css" />
|
||||
<link rel="stylesheet" href="Control.FullScreen.css" />
|
||||
<style type="text/css">
|
||||
#map { width: 700px; max-width: 100%; height: 433px; }
|
||||
</style>
|
||||
<script src="https://unpkg.com/leaflet@latest/dist/leaflet.js"></script>
|
||||
<script src="Control.FullScreen.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="map"></div>
|
||||
|
||||
<script>
|
||||
var base = L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png', {
|
||||
maxZoom: 19,
|
||||
subdomains: 'abcd',
|
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors © <a href="https://carto.com/attributions">CARTO</a>',
|
||||
});
|
||||
|
||||
var map = L.map('map', {
|
||||
layers: [base],
|
||||
tap: false, // ref https://github.com/Leaflet/Leaflet/issues/7255
|
||||
center: new L.LatLng(48.5, -4.5),
|
||||
zoom: 5,
|
||||
fullscreenControl: true,
|
||||
fullscreenControlOptions: { // optional
|
||||
title:"Show me the fullscreen !",
|
||||
titleCancel:"Exit fullscreen mode"
|
||||
}
|
||||
});
|
||||
|
||||
// detect fullscreen toggling
|
||||
map.on('enterFullscreen', function(){
|
||||
if(window.console) window.console.log('enterFullscreen');
|
||||
});
|
||||
map.on('exitFullscreen', function(){
|
||||
if(window.console) window.console.log('exitFullscreen');
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "leaflet.fullscreen",
|
||||
"version": "2.4.0",
|
||||
"description": "Simple plugin for Leaflet that adds fullscreen button to your maps.",
|
||||
"main": "Control.FullScreen.js",
|
||||
"scripts": {
|
||||
"lint": "eslint --config .eslintrc Control.FullScreen.js",
|
||||
"postversion": "git push && git push --tags && npm publish"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/brunob/leaflet.fullscreen.git"
|
||||
},
|
||||
"keywords": [
|
||||
"leaflet",
|
||||
"plugins",
|
||||
"maps",
|
||||
"fullscreen"
|
||||
],
|
||||
"devDependencies": {
|
||||
"eslint": "^8.1.0"
|
||||
},
|
||||
"author": "b_b",
|
||||
"license": "MIT License",
|
||||
"readmeFilename": "README.md"
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
Copyright (C) 2011-2012 Pavel Shramov
|
||||
Copyright (C) 2013 Maxime Petazzoni <maxime.petazzoni@bulix.org>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
@@ -0,0 +1,397 @@
|
||||
# GPX plugin for Leaflet
|
||||
|
||||
[](https://cdnjs.com/libraries/leaflet-gpx)
|
||||
|
||||
[Leaflet](http://www.leafletjs.com) is a Javascript library for displaying
|
||||
interactive maps. This plugin, based on the work of [Pavel
|
||||
Shramov](http://github.com/shramov) and his
|
||||
[leaflet-plugins](http://github.com/shramov/leaflet-plugins), it allows for the
|
||||
analysis and parsing of a GPX track in order to display it as a Leaflet map
|
||||
layer. As it parses the GPX data, it will record information about the recorded
|
||||
track, including total time, moving time, total distance, elevation stats and
|
||||
heart-rate.
|
||||
|
||||
GPX parsing will automatically handle pauses in the track with a default
|
||||
tolerance interval of 15 seconds between points. You can configure this
|
||||
interval by setting `max_point_interval`, in milliseconds, in the options
|
||||
passed to the `GPX` constructor.
|
||||
|
||||
I've put together a complete example as a
|
||||
[demo](http://mpetazzoni.github.com/leaflet-gpx/).
|
||||
|
||||
## License
|
||||
|
||||
`leaflet-gpx` is under the *BSD 2-clause license*. Please refer to the
|
||||
attached LICENSE file and/or to the copyright header in gpx.js for more
|
||||
information.
|
||||
|
||||
## Usage
|
||||
|
||||
Usage is very simple. First, include the Leaflet.js and Leaflet-GPX
|
||||
scripts in your HTML page:
|
||||
|
||||
```html
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet.css" />
|
||||
<!-- ... -->
|
||||
</head>
|
||||
<body>
|
||||
<!-- ... -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-gpx/1.5.1/gpx.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
Now, let's consider we have a Leaflet map:
|
||||
|
||||
```javascript
|
||||
var map = L.map('map');
|
||||
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
attribution: 'Map data © <a href="http://www.osm.org">OpenStreetMap</a>'
|
||||
}).addTo(map);
|
||||
```
|
||||
|
||||
Displaying a GPX track on it is as easy as:
|
||||
|
||||
```javascript
|
||||
var gpx = '...'; // URL to your GPX file or the GPX itself
|
||||
new L.GPX(gpx, {async: true}).on('loaded', function(e) {
|
||||
map.fitBounds(e.target.getBounds());
|
||||
}).addTo(map);
|
||||
```
|
||||
|
||||
Some GPX tracks contain the actual route/track twice, both the `<trk>` and
|
||||
`<rte>` elements are used. You can tell `leaflet-gpx` which tag to use or to
|
||||
use both (which is the default setting for backwards compatibility) with the
|
||||
`gpx_options` object in the second argument of the constructor. The member
|
||||
`parseElements` controls this behavior, it should be an array that contains
|
||||
`'route'` and/or `'track'`.
|
||||
|
||||
### Available functions
|
||||
|
||||
If you want to display additional information about the GPX track, you can do
|
||||
so in the 'loaded' event handler, calling one of the following methods on the
|
||||
`GPX` object `e.target`:
|
||||
|
||||
* `get_name()`: returns the name of the GPX track
|
||||
* `get_distance()`: returns the total track distance, in meters
|
||||
* `get_start_time()`: returns a Javascript `Date` object representing the
|
||||
starting time
|
||||
* `get_end_time()`: returns a Javascript `Date` object representing when the
|
||||
last point was recorded
|
||||
* `get_moving_time()`: returns the moving time, in milliseconds
|
||||
* `get_total_time()`: returns the total track time, in milliseconds
|
||||
* `get_moving_pace()`: returns the average moving pace in milliseconds per km
|
||||
* `get_moving_speed()`: returns the average moving speed in km per hour
|
||||
* `get_total_speed()`: returns the average total speed in km per hour
|
||||
* `get_elevation_min()`: returns the lowest elevation, in meters
|
||||
* `get_elevation_max()`: returns the highest elevation, in meters
|
||||
* `get_elevation_gain()`: returns the cumulative elevation gain, in meters
|
||||
* `get_elevation_loss()`: returns the cumulative elevation loss, in meters
|
||||
* `get_average_hr()`: returns the average heart rate (if available)
|
||||
* `get_average_cadence()`: returns the average cadence (if available)
|
||||
* `get_average_temp()`: returns the average of the temperature (if available)
|
||||
|
||||
If you're not a fan of the metric system, you also have the following methods
|
||||
at your disposal:
|
||||
|
||||
* `get_distance_imp()`: returns the total track distance in miles
|
||||
* `get_moving_pace_imp()`: returns the average moving pace in milliseconds per
|
||||
hour
|
||||
* `get_moving_speed_imp()`: returns the average moving speed in miles per hour
|
||||
* `get_total_speed_imp()`: returns the average total speed in miles per hour
|
||||
* `get_elevation_min_imp()`: returns the lowest elevation, in feet
|
||||
* `get_elevation_max_imp()`: returns the highest elevation, in feet
|
||||
* `get_elevation_gain_imp()`: returns the cumulative elevation gain, in feet
|
||||
* `get_elevation_loss_imp()`: returns the cumulative elevation loss, in feet
|
||||
|
||||
The reason why these methods return milliseconds is that you have at your
|
||||
disposal nice helper methods to format a duration in milliseconds into a cool
|
||||
string:
|
||||
|
||||
* `get_duration_string(duration, hidems)` format to a string like `3:07'48"`
|
||||
or `59'32.431`, where `duration` is in
|
||||
milliseconds and `hidems` is an optional boolean you can use to request never
|
||||
to display millisecond precision.
|
||||
* `get_duration_string_iso(duration, hidems)` formats to an ISO like
|
||||
representation like `3:07:48` or `59:32.431`, where `duration` is in
|
||||
milliseconds and `hidems` is an optional boolean you can use to request never
|
||||
to display millisecond precision.
|
||||
|
||||
You can also get full elevation, heartrate, cadence and temperature data with:
|
||||
|
||||
* `get_elevation_data()` and `get_elevation_data_imp()`
|
||||
* `get_heartrate_data()` and `get_heartrate_data_imp()`
|
||||
* `get_cadence_data()` and `get_cadence_data_imp()`
|
||||
* `get_temp_data()` and `get_temp_data_imp()`
|
||||
|
||||
These methods all return an array of points `[distance, value, tooltip]` where
|
||||
the distance is either in kilometers or in miles and the elevation in meters or
|
||||
feet, depending on whether you use the `_imp` variant or not. Heart rate,
|
||||
obviously, doesn't change.
|
||||
|
||||
### Reloading
|
||||
|
||||
You can make `leaflet-gpx` reload the source GPX file by calling the
|
||||
`reload()` method. For example, to trigger a reload every 5 seconds, you
|
||||
can do:
|
||||
|
||||
```javascript
|
||||
var gpx = new L.GPX(gpxFile);
|
||||
setInterval(function() {
|
||||
gpx.reload();
|
||||
}, 5000);
|
||||
```
|
||||
|
||||
## About marker icons
|
||||
|
||||
By default `gpx.js` will use `pin-icon-start.png`, `pin-icon-end.png` and
|
||||
`pin-shadow.png` as the marker icons URLs for, respectively, the start marker,
|
||||
the end marker and their drop shadow. Since it might not be convenient that
|
||||
these images have to reside under the same directory as your HTML page, it is
|
||||
possible to override the marker icon URLs and sizes by passing a
|
||||
`marker_options` object to the `GPX` options object.
|
||||
|
||||
The field names are the same as for custom Leaflet icons, as explained in the
|
||||
[Markers with custom icons](http://leafletjs.com/examples/custom-icons.html)
|
||||
page in Leaflet's documentation. The only difference is that instead of
|
||||
`iconUrl` you should specify `startIconUrl` and `endIconUrl` for the start and
|
||||
end markers, respectively.
|
||||
|
||||
Note that you do not need to override all the marker icon options as `gpx.js`
|
||||
will use sensible defaults with sizes matching the provided icon images. Here
|
||||
is how you would override the URL of the provided icons if you decided to place
|
||||
them in an `images/` directory:
|
||||
|
||||
```javascript
|
||||
var url = '...'; // URL to your GPX file
|
||||
new L.GPX(url, {
|
||||
async: true,
|
||||
marker_options: {
|
||||
startIconUrl: 'images/pin-icon-start.png',
|
||||
endIconUrl: 'images/pin-icon-end.png',
|
||||
shadowUrl: 'images/pin-shadow.png'
|
||||
}
|
||||
}).on('loaded', function(e) {
|
||||
map.fitBounds(e.target.getBounds());
|
||||
}).addTo(map);
|
||||
```
|
||||
|
||||
## About waypoints
|
||||
|
||||
By default `gpx.js` will parse Waypoints from a GPX file. This may also
|
||||
be steered via the value `waypoint` in `gpx_options`, e.g.
|
||||
`parseElements: ['track', 'route', 'waypoint']`.
|
||||
|
||||
Waypoint icons: by default the `pin-icon-wpt.png` icon is shown for each
|
||||
waypoint. This can be overridden by setting `marker_options.wptIconUrls`
|
||||
in the `L.GPX` constructor options, as a mapping from the waypoint "SYM"
|
||||
name to a user-supplied icon file or URL. The empty string `''` is used
|
||||
by the waypoint tag does not define a "SYM" name. See the example below:
|
||||
|
||||
```javascript
|
||||
new L.GPX(app.params.gpx_url, {
|
||||
async: true,
|
||||
marker_options: {
|
||||
wptIconUrls: {
|
||||
'': 'img/gpx/default-waypoint.png',
|
||||
'Geocache Found': 'img/gpx/geocache.png',
|
||||
'Park': 'img/gpx/tree.png'
|
||||
},
|
||||
...
|
||||
shadowUrl: 'http://github.com/mpetazzoni/leaflet-gpx/raw/master/pin-shadow.png'
|
||||
}
|
||||
}).on('loaded', function (e) {
|
||||
var gpx = e.target;
|
||||
map.fitBounds(gpx.getBounds());
|
||||
}).addTo(map);
|
||||
```
|
||||
|
||||
## Custom markers
|
||||
|
||||
You can also use your own icons/markers if you want to use custom
|
||||
markers, for example from `leaflet-awesome-markers`. To specify you own
|
||||
markers, set `startIcon`, `endIcon`, and a map of `wptIcons` by waypoint
|
||||
symbol (see above). Those should be marker icon objects usable by
|
||||
Leaflet as the `icon` property of a `L.Marker` object.
|
||||
|
||||
```javascript
|
||||
new L.GPX(app.params.gpx_url, {
|
||||
async: true,
|
||||
marker_options: {
|
||||
wptIcons: {
|
||||
'Coffee shop': new L.AwesomeMarkers.icon({
|
||||
icon: 'coffee',
|
||||
prefix: 'fa',
|
||||
markerColor: 'blue',
|
||||
iconColor: 'white'
|
||||
})
|
||||
}
|
||||
}
|
||||
}).on('loaded', function (e) {
|
||||
var gpx = e.target;
|
||||
map.fitBounds(gpx.getBounds());
|
||||
}).addTo(map);
|
||||
```
|
||||
|
||||
## Named points
|
||||
|
||||
GPX points can be named, for example to denote certain POIs (points of
|
||||
interest). You can setup rules to match point names to create labeled
|
||||
markers for those points by providing a `pointMatchers` array in the
|
||||
`marker_options`. Each element in this array must define a `regex` to
|
||||
match the point's name and an `icon` object (any `L.Marker` or
|
||||
for example an `L.AwesomeMarkers.icon` as shown above in _Custom
|
||||
markers_).
|
||||
|
||||
Each named point in the GPX track is evaluated against those rules and
|
||||
a marker is created with the point's name as label from the first
|
||||
matching rule. This also applies to named waypoints, but keep in mind
|
||||
that waypoint icons rules take precedence over point matchers.
|
||||
|
||||
```javascript
|
||||
new L.GPX(app.params.gpx_url, {
|
||||
async: true,
|
||||
marker_options: {
|
||||
pointMatchers: [
|
||||
{
|
||||
regex: /Coffee/,
|
||||
icon: new L.AwesomeMarkers.icon({
|
||||
icon: 'coffee',
|
||||
markerColor: 'blue',
|
||||
iconColor: 'white'
|
||||
}),
|
||||
},
|
||||
{
|
||||
regex: /Home/,
|
||||
icon: new L.AwesomeMarkers.icon({
|
||||
icon: 'home',
|
||||
markerColor: 'green',
|
||||
iconColor: 'white'
|
||||
}),
|
||||
}
|
||||
]
|
||||
}
|
||||
}).on('loaded', function(e) {
|
||||
var gpx = e.target;
|
||||
map.fitToBounds(gpx.getBounds());
|
||||
}).addTo(map);
|
||||
```
|
||||
|
||||
## Events
|
||||
|
||||
Events are fired on the `L.GPX` object as the GPX data is being parsed
|
||||
and the map layers generated. You can listen for those events by
|
||||
attaching the corresponding event listener on the `L.GPX` object:
|
||||
|
||||
```javascript
|
||||
new L.GPX(app.params.gpx_url, {
|
||||
// options
|
||||
}).on('addpoint', function(e) {
|
||||
console.log('Added ' + e.point_type + ' point: ' + e.point);
|
||||
}).on('loaded', function(e) {
|
||||
var gpx = e.target;
|
||||
map.fitToBounds(gpx.getBounds());
|
||||
}).on('error', function(e) {
|
||||
console.log('Error loading file: ' + e.err);
|
||||
}).addTo(map);
|
||||
```
|
||||
|
||||
`addpoint` events are fired for every marker added to the map, in
|
||||
particular for the start and end points, all the waypoints, and all the
|
||||
named points that matched `pointMatchers` rules. Each `addpoint` event
|
||||
contains the following properties:
|
||||
|
||||
- `point`: the marker object itself, from which you can get or modify
|
||||
the latitude and longitude of the point and any other attribute of the
|
||||
marker.
|
||||
- `point_type`: one of `start`, `end`, `waypoint` or `label`, allowing
|
||||
you to identify what type of point the marker is for.
|
||||
- `element`: the track point element the marker was created for.
|
||||
|
||||
One use case for those events is for example to attach additional
|
||||
content or behavior to the markers that were generated (popups, etc).
|
||||
|
||||
`error` events are fired when no layers of the type(s) specified in
|
||||
`options.gpx_options.parseElements` can be parsed out of the given
|
||||
file. For instance, `error` would be fired if a file with no waypoints
|
||||
was attempted to be loaded with `parseElements` set to `['waypoint']`.
|
||||
Each `error` event contains the following property:
|
||||
|
||||
- `err`: a message with details about the error that occurred.
|
||||
|
||||
## Line styling
|
||||
|
||||
`leaflet-gpx` understands the [GPX
|
||||
Style](http://www.topografix.com/GPX/gpx_style/0/2) extension, and will
|
||||
extract styling information defined on routes and track segments to use
|
||||
for drawing the corresponding polyline.
|
||||
|
||||
```xml
|
||||
<trkseg>
|
||||
<extensions>
|
||||
<line xmlns="http://www.topografix.com/GPX/gpx_style/0/2">
|
||||
<color>FF0000</color>
|
||||
<opacity>0.5</opacity>
|
||||
<weight>1</weight>
|
||||
<linecap>square</linecap>
|
||||
</line>
|
||||
</extensions>
|
||||
<trkpt lat="..." lon="..."></trkpt>
|
||||
</trkseg>
|
||||
```
|
||||
|
||||
You can override the style of the lines by passing a `polyline_options`
|
||||
object into the `options` argument of the `L.GPX` constructor:
|
||||
|
||||
```javascript
|
||||
new L.GPX(url, {
|
||||
polyline_options: {
|
||||
color: 'green',
|
||||
opacity: 0.75,
|
||||
weight: 3,
|
||||
lineCap: 'round'
|
||||
}
|
||||
}).on('loaded', function(e) {
|
||||
var gpx = e.target;
|
||||
map.fitToBounds(gpx.getBounds());
|
||||
}).addTo(map);
|
||||
```
|
||||
|
||||
For more information on the available polyline styling options, refer to
|
||||
the [Leaflet documentation on
|
||||
Polyline](https://leafletjs.com/reference-1.3.0.html#polyline). By
|
||||
default, if no styling is available, the line will be drawn in _blue_.
|
||||
|
||||
## GPX parsing options
|
||||
|
||||
### Multiple track segments within each track
|
||||
|
||||
GPX file may contain multiple tracks represented by `<trk>` elements,
|
||||
each track possibly composed of multiple segments with `<trkseg>`
|
||||
elements. Although this plugin will always represent each GPX route and
|
||||
each GPX track as distinct entities with their own start and end
|
||||
markers, track segments will by default be joined into a single line.
|
||||
|
||||
You can disable this behavior by setting the `joinTrackSegments` flag to
|
||||
`false` in the `gpx_options`:
|
||||
|
||||
```javascript
|
||||
new L.GPX(url, {
|
||||
gpx_options: {
|
||||
joinTrackSegments: false
|
||||
}
|
||||
}).on('loaded', function(e) {
|
||||
map.fitBounds(e.target.getBounds());
|
||||
}).addTo(map);
|
||||
```
|
||||
|
||||
## Caveats
|
||||
|
||||
* Distance calculation is relatively accurate, but elevation change
|
||||
calculation is not topographically adjusted, so the total elevation
|
||||
gain/loss/change might appear inaccurate in some situations.
|
||||
* Currently doesn't seem to work in IE8/9. See #9 and #11 for
|
||||
discussion.
|
||||
@@ -0,0 +1,619 @@
|
||||
/**
|
||||
* Copyright (C) 2011-2012 Pavel Shramov
|
||||
* Copyright (C) 2013-2017 Maxime Petazzoni <maxime.petazzoni@bulix.org>
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Thanks to Pavel Shramov who provided the initial implementation and Leaflet
|
||||
* integration. Original code was at https://github.com/shramov/leaflet-plugins.
|
||||
*
|
||||
* It was then cleaned-up and modified to record and make available more
|
||||
* information about the GPX track while it is being parsed so that the result
|
||||
* can be used to display additional information about the track that is
|
||||
* rendered on the Leaflet map.
|
||||
*/
|
||||
|
||||
var L = L || require('leaflet');
|
||||
|
||||
var _MAX_POINT_INTERVAL_MS = 15000;
|
||||
var _SECOND_IN_MILLIS = 1000;
|
||||
var _MINUTE_IN_MILLIS = 60 * _SECOND_IN_MILLIS;
|
||||
var _HOUR_IN_MILLIS = 60 * _MINUTE_IN_MILLIS;
|
||||
var _DAY_IN_MILLIS = 24 * _HOUR_IN_MILLIS;
|
||||
|
||||
var _GPX_STYLE_NS = 'http://www.topografix.com/GPX/gpx_style/0/2';
|
||||
|
||||
var _DEFAULT_MARKER_OPTS = {
|
||||
startIconUrl: 'pin-icon-start.png',
|
||||
endIconUrl: 'pin-icon-end.png',
|
||||
shadowUrl: 'pin-shadow.png',
|
||||
wptIcons: [],
|
||||
wptIconsType: [],
|
||||
wptIconUrls : {
|
||||
'': 'pin-icon-wpt.png',
|
||||
},
|
||||
wptIconTypeUrls : {
|
||||
'': 'pin-icon-wpt.png',
|
||||
},
|
||||
pointMatchers: [],
|
||||
iconSize: [33, 50],
|
||||
shadowSize: [50, 50],
|
||||
iconAnchor: [16, 45],
|
||||
shadowAnchor: [16, 47],
|
||||
clickable: false
|
||||
};
|
||||
var _DEFAULT_POLYLINE_OPTS = {
|
||||
color: 'blue'
|
||||
};
|
||||
var _DEFAULT_GPX_OPTS = {
|
||||
parseElements: ['track', 'route', 'waypoint'],
|
||||
joinTrackSegments: true
|
||||
};
|
||||
|
||||
L.GPX = L.FeatureGroup.extend({
|
||||
initialize: function(gpx, options) {
|
||||
options.max_point_interval = options.max_point_interval || _MAX_POINT_INTERVAL_MS;
|
||||
options.marker_options = this._merge_objs(
|
||||
_DEFAULT_MARKER_OPTS,
|
||||
options.marker_options || {});
|
||||
options.polyline_options = options.polyline_options || {};
|
||||
options.gpx_options = this._merge_objs(
|
||||
_DEFAULT_GPX_OPTS,
|
||||
options.gpx_options || {});
|
||||
|
||||
L.Util.setOptions(this, options);
|
||||
|
||||
// Base icon class for track pins.
|
||||
L.GPXTrackIcon = L.Icon.extend({ options: options.marker_options });
|
||||
|
||||
this._gpx = gpx;
|
||||
this._layers = {};
|
||||
this._init_info();
|
||||
|
||||
if (gpx) {
|
||||
this._parse(gpx, options, this.options.async);
|
||||
}
|
||||
},
|
||||
|
||||
get_duration_string: function(duration, hidems) {
|
||||
var s = '';
|
||||
|
||||
if (duration >= _DAY_IN_MILLIS) {
|
||||
s += Math.floor(duration / _DAY_IN_MILLIS) + 'd ';
|
||||
duration = duration % _DAY_IN_MILLIS;
|
||||
}
|
||||
|
||||
if (duration >= _HOUR_IN_MILLIS) {
|
||||
s += Math.floor(duration / _HOUR_IN_MILLIS) + ':';
|
||||
duration = duration % _HOUR_IN_MILLIS;
|
||||
}
|
||||
|
||||
var mins = Math.floor(duration / _MINUTE_IN_MILLIS);
|
||||
duration = duration % _MINUTE_IN_MILLIS;
|
||||
if (mins < 10) s += '0';
|
||||
s += mins + '\'';
|
||||
|
||||
var secs = Math.floor(duration / _SECOND_IN_MILLIS);
|
||||
duration = duration % _SECOND_IN_MILLIS;
|
||||
if (secs < 10) s += '0';
|
||||
s += secs;
|
||||
|
||||
if (!hidems && duration > 0) s += '.' + Math.round(Math.floor(duration)*1000)/1000;
|
||||
else s += '"';
|
||||
|
||||
return s;
|
||||
},
|
||||
|
||||
get_duration_string_iso: function(duration, hidems) {
|
||||
var s = this.get_duration_string(duration, hidems);
|
||||
return s.replace("'",':').replace('"','');
|
||||
},
|
||||
|
||||
// Public methods
|
||||
to_miles: function(v) { return v / 1.60934; },
|
||||
to_ft: function(v) { return v * 3.28084; },
|
||||
m_to_km: function(v) { return v / 1000; },
|
||||
m_to_mi: function(v) { return v / 1609.34; },
|
||||
|
||||
get_name: function() { return this._info.name; },
|
||||
get_desc: function() { return this._info.desc; },
|
||||
get_author: function() { return this._info.author; },
|
||||
get_copyright: function() { return this._info.copyright; },
|
||||
get_distance: function() { return this._info.length; },
|
||||
get_distance_imp: function() { return this.to_miles(this.m_to_km(this.get_distance())); },
|
||||
|
||||
get_start_time: function() { return this._info.duration.start; },
|
||||
get_end_time: function() { return this._info.duration.end; },
|
||||
get_moving_time: function() { return this._info.duration.moving; },
|
||||
get_total_time: function() { return this._info.duration.total; },
|
||||
|
||||
get_moving_pace: function() { return this.get_moving_time() / this.m_to_km(this.get_distance()); },
|
||||
get_moving_pace_imp: function() { return this.get_moving_time() / this.get_distance_imp(); },
|
||||
|
||||
get_moving_speed: function() { return this.m_to_km(this.get_distance()) / (this.get_moving_time() / (3600 * 1000)) ; },
|
||||
get_moving_speed_imp:function() { return this.to_miles(this.m_to_km(this.get_distance())) / (this.get_moving_time() / (3600 * 1000)) ; },
|
||||
|
||||
get_total_speed: function() { return this.m_to_km(this.get_distance()) / (this.get_total_time() / (3600 * 1000)); },
|
||||
get_total_speed_imp: function() { return this.to_miles(this.m_to_km(this.get_distance())) / (this.get_total_time() / (3600 * 1000)); },
|
||||
|
||||
get_elevation_gain: function() { return this._info.elevation.gain; },
|
||||
get_elevation_loss: function() { return this._info.elevation.loss; },
|
||||
get_elevation_gain_imp: function() { return this.to_ft(this.get_elevation_gain()); },
|
||||
get_elevation_loss_imp: function() { return this.to_ft(this.get_elevation_loss()); },
|
||||
get_elevation_data: function() {
|
||||
var _this = this;
|
||||
return this._info.elevation._points.map(
|
||||
function(p) { return _this._prepare_data_point(p, _this.m_to_km, null,
|
||||
function(a, b) { return a.toFixed(2) + ' km, ' + b.toFixed(0) + ' m'; });
|
||||
});
|
||||
},
|
||||
get_elevation_data_imp: function() {
|
||||
var _this = this;
|
||||
return this._info.elevation._points.map(
|
||||
function(p) { return _this._prepare_data_point(p, _this.m_to_mi, _this.to_ft,
|
||||
function(a, b) { return a.toFixed(2) + ' mi, ' + b.toFixed(0) + ' ft'; });
|
||||
});
|
||||
},
|
||||
get_elevation_max: function() { return this._info.elevation.max; },
|
||||
get_elevation_min: function() { return this._info.elevation.min; },
|
||||
get_elevation_max_imp: function() { return this.to_ft(this.get_elevation_max()); },
|
||||
get_elevation_min_imp: function() { return this.to_ft(this.get_elevation_min()); },
|
||||
|
||||
get_average_hr: function() { return this._info.hr.avg; },
|
||||
get_average_temp: function() { return this._info.atemp.avg; },
|
||||
get_average_cadence: function() { return this._info.cad.avg; },
|
||||
get_heartrate_data: function() {
|
||||
var _this = this;
|
||||
return this._info.hr._points.map(
|
||||
function(p) { return _this._prepare_data_point(p, _this.m_to_km, null,
|
||||
function(a, b) { return a.toFixed(2) + ' km, ' + b.toFixed(0) + ' bpm'; });
|
||||
});
|
||||
},
|
||||
get_heartrate_data_imp: function() {
|
||||
var _this = this;
|
||||
return this._info.hr._points.map(
|
||||
function(p) { return _this._prepare_data_point(p, _this.m_to_mi, null,
|
||||
function(a, b) { return a.toFixed(2) + ' mi, ' + b.toFixed(0) + ' bpm'; });
|
||||
});
|
||||
},
|
||||
get_cadence_data: function() {
|
||||
var _this = this;
|
||||
return this._info.cad._points.map(
|
||||
function(p) { return _this._prepare_data_point(p, _this.m_to_km, null,
|
||||
function(a, b) { return a.toFixed(2) + ' km, ' + b.toFixed(0) + ' rpm'; });
|
||||
});
|
||||
},
|
||||
get_temp_data: function() {
|
||||
var _this = this;
|
||||
return this._info.atemp._points.map(
|
||||
function(p) { return _this._prepare_data_point(p, _this.m_to_km, null,
|
||||
function(a, b) { return a.toFixed(2) + ' km, ' + b.toFixed(0) + ' degrees'; });
|
||||
});
|
||||
},
|
||||
get_cadence_data_imp: function() {
|
||||
var _this = this;
|
||||
return this._info.cad._points.map(
|
||||
function(p) { return _this._prepare_data_point(p, _this.m_to_mi, null,
|
||||
function(a, b) { return a.toFixed(2) + ' mi, ' + b.toFixed(0) + ' rpm'; });
|
||||
});
|
||||
},
|
||||
get_temp_data_imp: function() {
|
||||
var _this = this;
|
||||
return this._info.atemp._points.map(
|
||||
function(p) { return _this._prepare_data_point(p, _this.m_to_mi, null,
|
||||
function(a, b) { return a.toFixed(2) + ' mi, ' + b.toFixed(0) + ' degrees'; });
|
||||
});
|
||||
},
|
||||
|
||||
reload: function() {
|
||||
this._init_info();
|
||||
this.clearLayers();
|
||||
this._parse(this._gpx, this.options, this.options.async);
|
||||
},
|
||||
|
||||
// Private methods
|
||||
_merge_objs: function(a, b) {
|
||||
var _ = {};
|
||||
for (var attr in a) { _[attr] = a[attr]; }
|
||||
for (var attr in b) { _[attr] = b[attr]; }
|
||||
return _;
|
||||
},
|
||||
|
||||
_prepare_data_point: function(p, trans1, trans2, trans_tooltip) {
|
||||
var r = [trans1 && trans1(p[0]) || p[0], trans2 && trans2(p[1]) || p[1]];
|
||||
r.push(trans_tooltip && trans_tooltip(r[0], r[1]) || (r[0] + ': ' + r[1]));
|
||||
return r;
|
||||
},
|
||||
|
||||
_init_info: function() {
|
||||
this._info = {
|
||||
name: null,
|
||||
length: 0.0,
|
||||
elevation: {gain: 0.0, loss: 0.0, max: 0.0, min: Infinity, _points: []},
|
||||
hr: {avg: 0, _total: 0, _points: []},
|
||||
duration: {start: null, end: null, moving: 0, total: 0},
|
||||
atemp: {avg: 0, _total: 0, _points: []},
|
||||
cad: {avg: 0, _total: 0, _points: []}
|
||||
};
|
||||
},
|
||||
|
||||
_load_xml: function(url, cb, options, async) {
|
||||
if (async == undefined) async = this.options.async;
|
||||
if (options == undefined) options = this.options;
|
||||
|
||||
var req = new window.XMLHttpRequest();
|
||||
req.open('GET', url, async);
|
||||
try {
|
||||
req.overrideMimeType('text/xml'); // unsupported by IE
|
||||
} catch(e) {}
|
||||
req.onreadystatechange = function() {
|
||||
if (req.readyState != 4) return;
|
||||
if(req.status == 200) cb(req.responseXML, options);
|
||||
};
|
||||
req.send(null);
|
||||
},
|
||||
|
||||
_parse: function(input, options, async) {
|
||||
var _this = this;
|
||||
var cb = function(gpx, options) {
|
||||
var layers = _this._parse_gpx_data(gpx, options);
|
||||
if (!layers) {
|
||||
_this.fire('error', { err: 'No parseable layers of type(s) ' + JSON.stringify(options.gpx_options.parseElements) });
|
||||
return;
|
||||
}
|
||||
_this.addLayer(layers);
|
||||
_this.fire('loaded', { layers: layers, element: gpx });
|
||||
}
|
||||
if (input.substr(0,1)==='<') { // direct XML has to start with a <
|
||||
var parser = new DOMParser();
|
||||
if (async) {
|
||||
setTimeout(function() {
|
||||
cb(parser.parseFromString(input, "text/xml"), options);
|
||||
});
|
||||
} else {
|
||||
cb(parser.parseFromString(input, "text/xml"), options);
|
||||
}
|
||||
} else {
|
||||
this._load_xml(input, cb, options, async);
|
||||
}
|
||||
},
|
||||
|
||||
_parse_gpx_data: function(xml, options) {
|
||||
var i, t, l, el, layers = [];
|
||||
|
||||
var name = xml.getElementsByTagName('name');
|
||||
if (name.length > 0) {
|
||||
this._info.name = name[0].textContent;
|
||||
}
|
||||
var desc = xml.getElementsByTagName('desc');
|
||||
if (desc.length > 0) {
|
||||
this._info.desc = desc[0].textContent;
|
||||
}
|
||||
var author = xml.getElementsByTagName('author');
|
||||
if (author.length > 0) {
|
||||
this._info.author = author[0].textContent;
|
||||
}
|
||||
var copyright = xml.getElementsByTagName('copyright');
|
||||
if (copyright.length > 0) {
|
||||
this._info.copyright = copyright[0].textContent;
|
||||
}
|
||||
|
||||
var parseElements = options.gpx_options.parseElements;
|
||||
if (parseElements.indexOf('route') > -1) {
|
||||
// routes are <rtept> tags inside <rte> sections
|
||||
var routes = xml.getElementsByTagName('rte');
|
||||
for (i = 0; i < routes.length; i++) {
|
||||
layers = layers.concat(this._parse_segment(routes[i], options, {}, 'rtept'));
|
||||
}
|
||||
}
|
||||
|
||||
if (parseElements.indexOf('track') > -1) {
|
||||
// tracks are <trkpt> tags in one or more <trkseg> sections in each <trk>
|
||||
var tracks = xml.getElementsByTagName('trk');
|
||||
for (i = 0; i < tracks.length; i++) {
|
||||
var track = tracks[i];
|
||||
var polyline_options = this._extract_styling(track);
|
||||
|
||||
if (options.gpx_options.joinTrackSegments) {
|
||||
layers = layers.concat(this._parse_segment(track, options, polyline_options, 'trkpt'));
|
||||
} else {
|
||||
var segments = track.getElementsByTagName('trkseg');
|
||||
for (j = 0; j < segments.length; j++) {
|
||||
layers = layers.concat(this._parse_segment(segments[j], options, polyline_options, 'trkpt'));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this._info.hr.avg = Math.round(this._info.hr._total / this._info.hr._points.length);
|
||||
this._info.cad.avg = Math.round(this._info.cad._total / this._info.cad._points.length);
|
||||
this._info.atemp.avg = Math.round(this._info.atemp._total / this._info.atemp._points.length);
|
||||
|
||||
// parse waypoints and add markers for each of them
|
||||
if (parseElements.indexOf('waypoint') > -1) {
|
||||
el = xml.getElementsByTagName('wpt');
|
||||
for (i = 0; i < el.length; i++) {
|
||||
var ll = new L.LatLng(
|
||||
el[i].getAttribute('lat'),
|
||||
el[i].getAttribute('lon'));
|
||||
|
||||
var nameEl = el[i].getElementsByTagName('name');
|
||||
var name = nameEl.length > 0 ? nameEl[0].textContent : null;
|
||||
|
||||
var descEl = el[i].getElementsByTagName('desc');
|
||||
var desc = descEl.length > 0 ? descEl[0].textContent : null;
|
||||
|
||||
var symEl = el[i].getElementsByTagName('sym');
|
||||
var symKey = symEl.length > 0 ? symEl[0].textContent : null;
|
||||
|
||||
var typeEl = el[i].getElementsByTagName('type');
|
||||
var typeKey = typeEl.length > 0 ? typeEl[0].textContent : null;
|
||||
|
||||
/*
|
||||
* Add waypoint marker based on the waypoint symbol key.
|
||||
*
|
||||
* First look for a configured icon for that symKey. If not found, look
|
||||
* for a configured icon URL for that symKey and build an icon from it.
|
||||
* If none of those match, look through the point matchers for a match
|
||||
* on the waypoint's name.
|
||||
*
|
||||
* Otherwise, fall back to the default icon if one was configured, or
|
||||
* finally to the default icon URL, if one was configured.
|
||||
*/
|
||||
var wptIcons = options.marker_options.wptIcons;
|
||||
var wptIconUrls = options.marker_options.wptIconUrls;
|
||||
var wptIconsType = options.marker_options.wptIconsType;
|
||||
var wptIconTypeUrls = options.marker_options.wptIconTypeUrls;
|
||||
var ptMatchers = options.marker_options.pointMatchers || [];
|
||||
var symIcon;
|
||||
if (wptIcons && symKey && wptIcons[symKey]) {
|
||||
symIcon = wptIcons[symKey];
|
||||
} else if (wptIconsType && typeKey && wptIconsType[typeKey]) {
|
||||
symIcon = wptIconsType[typeKey];
|
||||
} else if (wptIconUrls && symKey && wptIconUrls[symKey]) {
|
||||
symIcon = new L.GPXTrackIcon({iconUrl: wptIconUrls[symKey]});
|
||||
} else if (wptIconTypeUrls && typeKey && wptIconTypeUrls[typeKey]) {
|
||||
symIcon = new L.GPXTrackIcon({iconUrl: wptIconTypeUrls[typeKey]});
|
||||
} else if (ptMatchers.length > 0) {
|
||||
for (var j = 0; j < ptMatchers.length; j++) {
|
||||
if (ptMatchers[j].regex.test(name)) {
|
||||
symIcon = ptMatchers[j].icon;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (wptIcons && wptIcons['']) {
|
||||
symIcon = wptIcons[''];
|
||||
} else if (wptIconUrls && wptIconUrls['']) {
|
||||
symIcon = new L.GPXTrackIcon({iconUrl: wptIconUrls['']});
|
||||
}
|
||||
|
||||
if (!symIcon) {
|
||||
console.log(
|
||||
'No waypoint icon could be matched for symKey=%s,typeKey=%s,name=%s on waypoint %o',
|
||||
symKey, typeKey, name, el[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
var marker = new L.Marker(ll, {
|
||||
clickable: options.marker_options.clickable,
|
||||
title: name,
|
||||
icon: symIcon,
|
||||
type: 'waypoint'
|
||||
});
|
||||
marker.bindPopup("<b>" + name + "</b>" + (desc.length > 0 ? '<br>' + desc : '')).openPopup();
|
||||
this.fire('addpoint', { point: marker, point_type: 'waypoint', element: el[i] });
|
||||
layers.push(marker);
|
||||
}
|
||||
}
|
||||
|
||||
if (layers.length > 1) {
|
||||
return new L.FeatureGroup(layers);
|
||||
} else if (layers.length == 1) {
|
||||
return layers[0];
|
||||
}
|
||||
},
|
||||
|
||||
_parse_segment: function(line, options, polyline_options, tag) {
|
||||
var el = line.getElementsByTagName(tag);
|
||||
if (!el.length) return [];
|
||||
|
||||
var coords = [];
|
||||
var markers = [];
|
||||
var layers = [];
|
||||
var last = null;
|
||||
|
||||
for (var i = 0; i < el.length; i++) {
|
||||
var _, ll = new L.LatLng(
|
||||
el[i].getAttribute('lat'),
|
||||
el[i].getAttribute('lon'));
|
||||
ll.meta = { time: null, ele: null, hr: null, cad: null, atemp: null };
|
||||
|
||||
_ = el[i].getElementsByTagName('time');
|
||||
if (_.length > 0) {
|
||||
ll.meta.time = new Date(Date.parse(_[0].textContent));
|
||||
} else {
|
||||
ll.meta.time = new Date('1970-01-01T00:00:00');
|
||||
}
|
||||
|
||||
_ = el[i].getElementsByTagName('ele');
|
||||
if (_.length > 0) {
|
||||
ll.meta.ele = parseFloat(_[0].textContent);
|
||||
}
|
||||
|
||||
_ = el[i].getElementsByTagName('name');
|
||||
if (_.length > 0) {
|
||||
var name = _[0].textContent;
|
||||
var ptMatchers = options.marker_options.pointMatchers || [];
|
||||
|
||||
for (var j = 0; j < ptMatchers.length; j++) {
|
||||
if (ptMatchers[j].regex.test(name)) {
|
||||
markers.push({ label: name, coords: ll, icon: ptMatchers[j].icon, element: el[i] });
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_ = el[i].getElementsByTagNameNS('*', 'hr');
|
||||
if (_.length > 0) {
|
||||
ll.meta.hr = parseInt(_[0].textContent);
|
||||
this._info.hr._points.push([this._info.length, ll.meta.hr]);
|
||||
this._info.hr._total += ll.meta.hr;
|
||||
}
|
||||
|
||||
_ = el[i].getElementsByTagNameNS('*', 'cad');
|
||||
if (_.length > 0) {
|
||||
ll.meta.cad = parseInt(_[0].textContent);
|
||||
this._info.cad._points.push([this._info.length, ll.meta.cad]);
|
||||
this._info.cad._total += ll.meta.cad;
|
||||
}
|
||||
|
||||
_ = el[i].getElementsByTagNameNS('*', 'atemp');
|
||||
if (_.length > 0) {
|
||||
ll.meta.atemp = parseInt(_[0].textContent);
|
||||
this._info.atemp._points.push([this._info.length, ll.meta.atemp]);
|
||||
this._info.atemp._total += ll.meta.atemp;
|
||||
}
|
||||
|
||||
if (ll.meta.ele > this._info.elevation.max) {
|
||||
this._info.elevation.max = ll.meta.ele;
|
||||
}
|
||||
|
||||
if (ll.meta.ele < this._info.elevation.min) {
|
||||
this._info.elevation.min = ll.meta.ele;
|
||||
}
|
||||
|
||||
this._info.elevation._points.push([this._info.length, ll.meta.ele]);
|
||||
this._info.duration.end = ll.meta.time;
|
||||
|
||||
if (last != null) {
|
||||
this._info.length += this._dist3d(last, ll);
|
||||
|
||||
var t = ll.meta.ele - last.meta.ele;
|
||||
if (t > 0) {
|
||||
this._info.elevation.gain += t;
|
||||
} else {
|
||||
this._info.elevation.loss += Math.abs(t);
|
||||
}
|
||||
|
||||
t = Math.abs(ll.meta.time - last.meta.time);
|
||||
this._info.duration.total += t;
|
||||
if (t < options.max_point_interval) {
|
||||
this._info.duration.moving += t;
|
||||
}
|
||||
} else if (this._info.duration.start == null) {
|
||||
this._info.duration.start = ll.meta.time;
|
||||
}
|
||||
|
||||
last = ll;
|
||||
coords.push(ll);
|
||||
}
|
||||
|
||||
// add track
|
||||
var l = new L.Polyline(coords, this._extract_styling(line, polyline_options, options.polyline_options));
|
||||
this.fire('addline', { line: l, element: line });
|
||||
layers.push(l);
|
||||
|
||||
if (options.marker_options.startIcon || options.marker_options.startIconUrl) {
|
||||
// add start pin
|
||||
var marker = new L.Marker(coords[0], {
|
||||
clickable: options.marker_options.clickable,
|
||||
icon: options.marker_options.startIcon || new L.GPXTrackIcon({iconUrl: options.marker_options.startIconUrl})
|
||||
});
|
||||
this.fire('addpoint', { point: marker, point_type: 'start', element: el[0] });
|
||||
layers.push(marker);
|
||||
}
|
||||
|
||||
if (options.marker_options.endIcon || options.marker_options.endIconUrl) {
|
||||
// add end pin
|
||||
var marker = new L.Marker(coords[coords.length-1], {
|
||||
clickable: options.marker_options.clickable,
|
||||
icon: options.marker_options.endIcon || new L.GPXTrackIcon({iconUrl: options.marker_options.endIconUrl})
|
||||
});
|
||||
this.fire('addpoint', { point: marker, point_type: 'end', element: el[el.length-1] });
|
||||
layers.push(marker);
|
||||
}
|
||||
|
||||
// add named markers
|
||||
for (var i = 0; i < markers.length; i++) {
|
||||
var marker = new L.Marker(markers[i].coords, {
|
||||
clickable: options.marker_options.clickable,
|
||||
title: markers[i].label,
|
||||
icon: markers[i].icon
|
||||
});
|
||||
this.fire('addpoint', { point: marker, point_type: 'label', element: markers[i].element });
|
||||
layers.push(marker);
|
||||
}
|
||||
|
||||
return layers;
|
||||
},
|
||||
|
||||
_extract_styling: function(el, base, overrides) {
|
||||
var style = this._merge_objs(_DEFAULT_POLYLINE_OPTS, base);
|
||||
var e = el.getElementsByTagNameNS(_GPX_STYLE_NS, 'line');
|
||||
if (e.length > 0) {
|
||||
var _ = e[0].getElementsByTagName('color');
|
||||
if (_.length > 0) style.color = '#' + _[0].textContent;
|
||||
var _ = e[0].getElementsByTagName('opacity');
|
||||
if (_.length > 0) style.opacity = _[0].textContent;
|
||||
var _ = e[0].getElementsByTagName('weight');
|
||||
if (_.length > 0) style.weight = _[0].textContent;
|
||||
var _ = e[0].getElementsByTagName('linecap');
|
||||
if (_.length > 0) style.lineCap = _[0].textContent;
|
||||
}
|
||||
return this._merge_objs(style, overrides)
|
||||
},
|
||||
|
||||
_dist2d: function(a, b) {
|
||||
var R = 6371000;
|
||||
var dLat = this._deg2rad(b.lat - a.lat);
|
||||
var dLon = this._deg2rad(b.lng - a.lng);
|
||||
var r = Math.sin(dLat/2) *
|
||||
Math.sin(dLat/2) +
|
||||
Math.cos(this._deg2rad(a.lat)) *
|
||||
Math.cos(this._deg2rad(b.lat)) *
|
||||
Math.sin(dLon/2) *
|
||||
Math.sin(dLon/2);
|
||||
var c = 2 * Math.atan2(Math.sqrt(r), Math.sqrt(1-r));
|
||||
var d = R * c;
|
||||
return d;
|
||||
},
|
||||
|
||||
_dist3d: function(a, b) {
|
||||
var planar = this._dist2d(a, b);
|
||||
var height = Math.abs(b.meta.ele - a.meta.ele);
|
||||
return Math.sqrt(Math.pow(planar, 2) + Math.pow(height, 2));
|
||||
},
|
||||
|
||||
_deg2rad: function(deg) {
|
||||
return deg * Math.PI / 180;
|
||||
}
|
||||
});
|
||||
|
||||
if (typeof module === 'object' && typeof module.exports === 'object') {
|
||||
module.exports = L;
|
||||
} else if (typeof define === 'function' && define.amd) {
|
||||
define(L);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "leaflet-gpx",
|
||||
"version": "1.5.1",
|
||||
"description": "A Leaflet plugin for showing a GPX track on a map",
|
||||
"main": "gpx.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/mpetazzoni/leaflet-gpx.git"
|
||||
},
|
||||
"keywords": [
|
||||
"leaflet",
|
||||
"gpx",
|
||||
"leaflet-gpx",
|
||||
"map",
|
||||
"gps"
|
||||
],
|
||||
"author": "Maxime Petazzoni <maxime.petazzoni@bulix.org> (https://www.bulix.org)",
|
||||
"license": "BSD-2-Clause",
|
||||
"bugs": {
|
||||
"url": "https://github.com/mpetazzoni/leaflet-gpx/issues"
|
||||
},
|
||||
"homepage": "https://github.com/mpetazzoni/leaflet-gpx#readme"
|
||||
}
|
||||
|
After Width: | Height: | Size: 960 B |
|
After Width: | Height: | Size: 971 B |
|
After Width: | Height: | Size: 660 B |
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,60 @@
|
||||
.marker-cluster-small {
|
||||
background-color: rgba(181, 226, 140, 0.6);
|
||||
}
|
||||
.marker-cluster-small div {
|
||||
background-color: rgba(110, 204, 57, 0.6);
|
||||
}
|
||||
|
||||
.marker-cluster-medium {
|
||||
background-color: rgba(241, 211, 87, 0.6);
|
||||
}
|
||||
.marker-cluster-medium div {
|
||||
background-color: rgba(240, 194, 12, 0.6);
|
||||
}
|
||||
|
||||
.marker-cluster-large {
|
||||
background-color: rgba(253, 156, 115, 0.6);
|
||||
}
|
||||
.marker-cluster-large div {
|
||||
background-color: rgba(241, 128, 23, 0.6);
|
||||
}
|
||||
|
||||
/* IE 6-8 fallback colors */
|
||||
.leaflet-oldie .marker-cluster-small {
|
||||
background-color: rgb(181, 226, 140);
|
||||
}
|
||||
.leaflet-oldie .marker-cluster-small div {
|
||||
background-color: rgb(110, 204, 57);
|
||||
}
|
||||
|
||||
.leaflet-oldie .marker-cluster-medium {
|
||||
background-color: rgb(241, 211, 87);
|
||||
}
|
||||
.leaflet-oldie .marker-cluster-medium div {
|
||||
background-color: rgb(240, 194, 12);
|
||||
}
|
||||
|
||||
.leaflet-oldie .marker-cluster-large {
|
||||
background-color: rgb(253, 156, 115);
|
||||
}
|
||||
.leaflet-oldie .marker-cluster-large div {
|
||||
background-color: rgb(241, 128, 23);
|
||||
}
|
||||
|
||||
.marker-cluster {
|
||||
background-clip: padding-box;
|
||||
border-radius: 20px;
|
||||
}
|
||||
.marker-cluster div {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
margin-left: 5px;
|
||||
margin-top: 5px;
|
||||
|
||||
text-align: center;
|
||||
border-radius: 15px;
|
||||
font: 12px "Helvetica Neue", Arial, Helvetica, sans-serif;
|
||||
}
|
||||
.marker-cluster span {
|
||||
line-height: 30px;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
.leaflet-cluster-anim .leaflet-marker-icon, .leaflet-cluster-anim .leaflet-marker-shadow {
|
||||
-webkit-transition: -webkit-transform 0.3s ease-out, opacity 0.3s ease-in;
|
||||
-moz-transition: -moz-transform 0.3s ease-out, opacity 0.3s ease-in;
|
||||
-o-transition: -o-transform 0.3s ease-out, opacity 0.3s ease-in;
|
||||
transition: transform 0.3s ease-out, opacity 0.3s ease-in;
|
||||
}
|
||||
|
||||
.leaflet-cluster-spider-leg {
|
||||
/* stroke-dashoffset (duration and function) should match with leaflet-marker-icon transform in order to track it exactly */
|
||||
-webkit-transition: -webkit-stroke-dashoffset 0.3s ease-out, -webkit-stroke-opacity 0.3s ease-in;
|
||||
-moz-transition: -moz-stroke-dashoffset 0.3s ease-out, -moz-stroke-opacity 0.3s ease-in;
|
||||
-o-transition: -o-stroke-dashoffset 0.3s ease-out, -o-stroke-opacity 0.3s ease-in;
|
||||
transition: stroke-dashoffset 0.3s ease-out, stroke-opacity 0.3s ease-in;
|
||||
}
|
||||
@@ -0,0 +1,292 @@
|
||||
Leaflet.markercluster
|
||||
=====================
|
||||
|
||||
Provides Beautiful Animated Marker Clustering functionality for [Leaflet](http://leafletjs.com), a JS library for interactive maps.
|
||||
|
||||
*Requires Leaflet 1.0.0*
|
||||
|
||||

|
||||
|
||||
For a Leaflet 0.7 compatible version, [use the leaflet-0.7 branch](https://github.com/Leaflet/Leaflet.markercluster/tree/leaflet-0.7)<br>
|
||||
For a Leaflet 0.5 compatible version, [Download b128e950](https://github.com/Leaflet/Leaflet.markercluster/archive/b128e950d8f5d7da5b60bd0aa9a88f6d3dd17c98.zip)<br>
|
||||
For a Leaflet 0.4 compatible version, [Download the 0.2 release](https://github.com/Leaflet/Leaflet.markercluster/archive/0.2.zip)
|
||||
|
||||
<!---
|
||||
TOC created with gh-md-toc
|
||||
https://github.com/ekalinin/github-markdown-toc
|
||||
removed link to h1 and indented back 2 spaces all links.
|
||||
-->
|
||||
## Table of Contents
|
||||
* [Using the plugin](#using-the-plugin)
|
||||
* [Building, testing and linting scripts](#building-testing-and-linting-scripts)
|
||||
* [Examples](#examples)
|
||||
* [Usage](#usage)
|
||||
* [Options](#options)
|
||||
* [Defaults](#defaults)
|
||||
* [Customising the Clustered Markers](#customising-the-clustered-markers)
|
||||
* [All Options](#all-options)
|
||||
* [Enabled by default (boolean options)](#enabled-by-default-boolean-options)
|
||||
* [Other options](#other-options)
|
||||
* [Chunked addLayers options](#chunked-addlayers-options)
|
||||
* [Events](#events)
|
||||
* [Additional MarkerClusterGroup Events](#additional-markerclustergroup-events)
|
||||
* [Methods](#methods)
|
||||
* [Group methods](#group-methods)
|
||||
* [Adding and removing Markers](#adding-and-removing-markers)
|
||||
* [Bulk adding and removing Markers](#bulk-adding-and-removing-markers)
|
||||
* [Getting the visible parent of a marker](#getting-the-visible-parent-of-a-marker)
|
||||
* [Refreshing the clusters icon](#refreshing-the-clusters-icon)
|
||||
* [Other Group Methods](#other-group-methods)
|
||||
* [Clusters methods](#clusters-methods)
|
||||
* [Getting the bounds of a cluster](#getting-the-bounds-of-a-cluster)
|
||||
* [Zooming to the bounds of a cluster](#zooming-to-the-bounds-of-a-cluster)
|
||||
* [Other clusters methods](#other-clusters-methods)
|
||||
* [Handling LOTS of markers](#handling-lots-of-markers)
|
||||
* [License](#license)
|
||||
* [Sub-plugins](#sub-plugins)
|
||||
|
||||
|
||||
## Using the plugin
|
||||
Include the plugin CSS and JS files on your page after Leaflet files, using your method of choice:
|
||||
* [Download the `v1.4.1` release](https://github.com/Leaflet/Leaflet.markercluster/archive/v1.4.1.zip)
|
||||
* Use unpkg CDN: `https://unpkg.com/leaflet.markercluster@1.4.1/dist/`
|
||||
* Install with npm: `npm install leaflet.markercluster`
|
||||
|
||||
In each case, use files in the `dist` folder:
|
||||
* `MarkerCluster.css`
|
||||
* `MarkerCluster.Default.css` (not needed if you use your own `iconCreateFunction` instead of the default one)
|
||||
* `leaflet.markercluster.js` (or `leaflet.markercluster-src.js` for the non-minified version)
|
||||
|
||||
### Building, testing and linting scripts
|
||||
Install jake `npm install -g jake` then run `npm install`
|
||||
* To check the code for errors and build Leaflet from source, run `jake`.
|
||||
* To run the tests, run `jake test`.
|
||||
|
||||
### Examples
|
||||
See the included examples for usage.
|
||||
|
||||
The [realworld example](https://leaflet.github.io/Leaflet.markercluster/example/marker-clustering-realworld.388.html) is a good place to start, it uses all of the defaults of the clusterer.
|
||||
Or check out the [custom example](https://leaflet.github.io/Leaflet.markercluster/example/marker-clustering-custom.html) for how to customise the behaviour and appearance of the clusterer
|
||||
|
||||
### Usage
|
||||
Create a new MarkerClusterGroup, add your markers to it, then add it to the map
|
||||
|
||||
```javascript
|
||||
var markers = L.markerClusterGroup();
|
||||
markers.addLayer(L.marker(getRandomLatLng(map)));
|
||||
... Add more layers ...
|
||||
map.addLayer(markers);
|
||||
```
|
||||
|
||||
## Options
|
||||
### Defaults
|
||||
By default the Clusterer enables some nice defaults for you:
|
||||
* **showCoverageOnHover**: When you mouse over a cluster it shows the bounds of its markers.
|
||||
* **zoomToBoundsOnClick**: When you click a cluster we zoom to its bounds.
|
||||
* **spiderfyOnMaxZoom**: When you click a cluster at the bottom zoom level we spiderfy it so you can see all of its markers. (*Note: the spiderfy occurs at the current zoom level if all items within the cluster are still clustered at the maximum zoom level or at zoom specified by `disableClusteringAtZoom` option*)
|
||||
* **removeOutsideVisibleBounds**: Clusters and markers too far from the viewport are removed from the map for performance.
|
||||
* **spiderLegPolylineOptions**: Allows you to specify [PolylineOptions](http://leafletjs.com/reference.html#polyline-options) to style spider legs. By default, they are `{ weight: 1.5, color: '#222', opacity: 0.5 }`.
|
||||
|
||||
You can disable any of these as you want in the options when you create the MarkerClusterGroup:
|
||||
```javascript
|
||||
var markers = L.markerClusterGroup({
|
||||
spiderfyOnMaxZoom: false,
|
||||
showCoverageOnHover: false,
|
||||
zoomToBoundsOnClick: false
|
||||
});
|
||||
```
|
||||
|
||||
### Customising the Clustered Markers
|
||||
As an option to MarkerClusterGroup you can provide your own function for creating the Icon for the clustered markers.
|
||||
The default implementation changes color at bounds of 10 and 100, but more advanced uses may require customising this.
|
||||
You do not need to include the .Default css if you go this way.
|
||||
You are passed a MarkerCluster object, you'll probably want to use `getChildCount()` or `getAllChildMarkers()` to work out the icon to show.
|
||||
|
||||
```javascript
|
||||
var markers = L.markerClusterGroup({
|
||||
iconCreateFunction: function(cluster) {
|
||||
return L.divIcon({ html: '<b>' + cluster.getChildCount() + '</b>' });
|
||||
}
|
||||
});
|
||||
```
|
||||
Check out the [custom example](https://leaflet.github.io/Leaflet.markercluster/example/marker-clustering-custom.html) for an example of this.
|
||||
|
||||
If you need to update the clusters icon (e.g. they are based on markers real-time data), use the method [refreshClusters()](#refreshing-the-clusters-icon).
|
||||
|
||||
### All Options
|
||||
#### Enabled by default (boolean options)
|
||||
* **showCoverageOnHover**: When you mouse over a cluster it shows the bounds of its markers.
|
||||
* **zoomToBoundsOnClick**: When you click a cluster we zoom to its bounds.
|
||||
* **spiderfyOnMaxZoom**: When you click a cluster at the bottom zoom level we spiderfy it so you can see all of its markers. (*Note: the spiderfy occurs at the current zoom level if all items within the cluster are still clustered at the maximum zoom level or at zoom specified by `disableClusteringAtZoom` option*).
|
||||
* **removeOutsideVisibleBounds**: Clusters and markers too far from the viewport are removed from the map for performance.
|
||||
* **animate**: Smoothly split / merge cluster children when zooming and spiderfying. If `L.DomUtil.TRANSITION` is false, this option has no effect (no animation is possible).
|
||||
|
||||
#### Other options
|
||||
* **animateAddingMarkers**: If set to true (and `animate` option is also true) then adding individual markers to the MarkerClusterGroup after it has been added to the map will add the marker and animate it into the cluster. Defaults to false as this gives better performance when bulk adding markers. addLayers does not support this, only addLayer with individual Markers.
|
||||
* **disableClusteringAtZoom**: If set, at this zoom level and below, markers will not be clustered. This defaults to disabled. [See Example](https://leaflet.github.io/Leaflet.markercluster/example/marker-clustering-realworld-maxzoom.388.html). Note: you may be interested in disabling `spiderfyOnMaxZoom` option when using `disableClusteringAtZoom`.
|
||||
* **maxClusterRadius**: The maximum radius that a cluster will cover from the central marker (in pixels). Default 80. Decreasing will make more, smaller clusters. You can also use a function that accepts the current map zoom and returns the maximum cluster radius in pixels.
|
||||
* **polygonOptions**: Options to pass when creating the L.Polygon(points, options) to show the bounds of a cluster. Defaults to empty, which lets Leaflet use the [default Path options](http://leafletjs.com/reference.html#path-options).
|
||||
* **singleMarkerMode**: If set to true, overrides the icon for all added markers to make them appear as a 1 size cluster. Note: the markers are not replaced by cluster objects, only their icon is replaced. Hence they still react to normal events, and option `disableClusteringAtZoom` does not restore their previous icon (see [#391](https://github.com/Leaflet/Leaflet.markercluster/issues/391)).
|
||||
* **spiderLegPolylineOptions**: Allows you to specify [PolylineOptions](http://leafletjs.com/reference.html#polyline-options) to style spider legs. By default, they are `{ weight: 1.5, color: '#222', opacity: 0.5 }`.
|
||||
* **spiderfyDistanceMultiplier**: Increase from 1 to increase the distance away from the center that spiderfied markers are placed. Use if you are using big marker icons (Default: 1).
|
||||
* **iconCreateFunction**: Function used to create the cluster icon. See [the default implementation](https://github.com/Leaflet/Leaflet.markercluster/blob/15ed12654acdc54a4521789c498e4603fe4bf781/src/MarkerClusterGroup.js#L542) or the [custom example](https://leaflet.github.io/Leaflet.markercluster/example/marker-clustering-custom.html).
|
||||
* **clusterPane**: Map pane where the cluster icons will be added. Defaults to L.Marker's default (currently 'markerPane'). [See the pane example](https://leaflet.github.io/Leaflet.markercluster/example/marker-clustering-pane.html).
|
||||
|
||||
#### Chunked addLayers options
|
||||
Options for the [addLayers](#bulk-adding-and-removing-markers) method. See [#357](https://github.com/Leaflet/Leaflet.markercluster/issues/357) for explanation on how the chunking works.
|
||||
* **chunkedLoading**: Boolean to split the addLayer**s** processing in to small intervals so that the page does not freeze.
|
||||
* **chunkInterval**: Time interval (in ms) during which addLayers works before pausing to let the rest of the page process. In particular, this prevents the page from freezing while adding a lot of markers. Defaults to 200ms.
|
||||
* **chunkDelay**: Time delay (in ms) between consecutive periods of processing for addLayers. Default to 50ms.
|
||||
* **chunkProgress**: Callback function that is called at the end of each chunkInterval. Typically used to implement a progress indicator, e.g. [code in RealWorld 50k](https://github.com/Leaflet/Leaflet.markercluster/blob/master/example/marker-clustering-realworld.50000.html#L33-L49). Defaults to null. Arguments:
|
||||
1. Number of processed markers
|
||||
2. Total number of markers being added
|
||||
3. Elapsed time (in ms)
|
||||
|
||||
## Events
|
||||
Leaflet events like `click`, `mouseover`, etc. are just related to _Markers_ in the cluster.
|
||||
To receive events for clusters, listen to `'cluster' + '<eventName>'`, ex: `clusterclick`, `clustermouseover`, `clustermouseout`.
|
||||
|
||||
Set your callback up as follows to handle both cases:
|
||||
|
||||
```javascript
|
||||
markers.on('click', function (a) {
|
||||
console.log('marker ' + a.layer);
|
||||
});
|
||||
|
||||
markers.on('clusterclick', function (a) {
|
||||
// a.layer is actually a cluster
|
||||
console.log('cluster ' + a.layer.getAllChildMarkers().length);
|
||||
});
|
||||
```
|
||||
|
||||
### Additional MarkerClusterGroup Events
|
||||
|
||||
- **animationend**: Fires when marker clustering/unclustering animation has completed
|
||||
- **spiderfied**: Fires when overlapping markers get spiderified (Contains ```cluster``` and ```markers``` attributes)
|
||||
- **unspiderfied**: Fires when overlapping markers get unspiderified (Contains ```cluster``` and ```markers``` attributes)
|
||||
|
||||
## Methods
|
||||
|
||||
### Group methods
|
||||
|
||||
#### Adding and removing Markers
|
||||
`addLayer`, `removeLayer` and `clearLayers` are supported and they should work for most uses.
|
||||
|
||||
#### Bulk adding and removing Markers
|
||||
`addLayers` and `removeLayers` are bulk methods for adding and removing markers and should be favoured over the single versions when doing bulk addition/removal of markers. Each takes an array of markers. You can use [dedicated options](#chunked-addlayers-options) to fine-tune the behaviour of `addLayers`.
|
||||
|
||||
These methods extract non-group layer children from Layer Group types, even deeply nested. _However_, be noted that:
|
||||
- `chunkProgress` jumps backward when `addLayers` finds a group (since appending its children to the input array makes the total increase).
|
||||
- Groups are not actually added into the MarkerClusterGroup, only their non-group child layers. Therfore, `hasLayer` method will return `true` for non-group child layers, but `false` on any (possibly parent) Layer Group types.
|
||||
|
||||
If you are removing a lot of markers it will almost definitely be better to call `clearLayers` then call `addLayers` to add the markers you don't want to remove back in. See [#59](https://github.com/Leaflet/Leaflet.markercluster/issues/59#issuecomment-9320628) for details.
|
||||
|
||||
#### Getting the visible parent of a marker
|
||||
If you have a marker in your MarkerClusterGroup and you want to get the visible parent of it (Either itself or a cluster it is contained in that is currently visible on the map).
|
||||
This will return null if the marker and its parent clusters are not visible currently (they are not near the visible viewpoint)
|
||||
```javascript
|
||||
var visibleOne = markerClusterGroup.getVisibleParent(myMarker);
|
||||
console.log(visibleOne.getLatLng());
|
||||
```
|
||||
|
||||
#### Refreshing the clusters icon
|
||||
If you have [customized](#customising-the-clustered-markers) the clusters icon to use some data from the contained markers, and later that data changes, use this method to force a refresh of the cluster icons.
|
||||
You can use the method:
|
||||
- without arguments to force all cluster icons in the Marker Cluster Group to be re-drawn.
|
||||
- with an array or a mapping of markers to force only their parent clusters to be re-drawn.
|
||||
- with an L.LayerGroup. The method will look for all markers in it. Make sure it contains only markers which are also within this Marker Cluster Group.
|
||||
- with a single marker.
|
||||
```javascript
|
||||
markers.refreshClusters();
|
||||
markers.refreshClusters([myMarker0, myMarker33]);
|
||||
markers.refreshClusters({id_0: myMarker0, id_any: myMarker33});
|
||||
markers.refreshClusters(myLayerGroup);
|
||||
markers.refreshClusters(myMarker);
|
||||
```
|
||||
|
||||
The plugin also adds a method on L.Marker to easily update the underlying icon options and refresh the icon.
|
||||
If passing a second argument that evaluates to `true`, the method will also trigger a `refreshCluster` on the parent MarkerClusterGroup for that single marker.
|
||||
```javascript
|
||||
// Use as many times as required to update markers,
|
||||
// then call refreshClusters once finished.
|
||||
for (i in markersSubArray) {
|
||||
markersSubArray[i].refreshIconOptions(newOptionsMappingArray[i]);
|
||||
}
|
||||
markers.refreshClusters(markersSubArray);
|
||||
|
||||
// If updating only one marker, pass true to
|
||||
// refresh this marker's parent clusters right away.
|
||||
myMarker.refreshIconOptions(optionsMap, true);
|
||||
```
|
||||
|
||||
#### Other Group Methods
|
||||
* **hasLayer**(layer): Returns true if the given layer (marker) is in the MarkerClusterGroup.
|
||||
* **zoomToShowLayer**(layer, callback): Zooms to show the given marker (spiderfying if required), calls the callback when the marker is visible on the map.
|
||||
|
||||
### Clusters methods
|
||||
The following methods can be used with clusters (not the group). They are typically used for event handling.
|
||||
|
||||
#### Getting the bounds of a cluster
|
||||
When you receive an event from a cluster you can query it for the bounds.
|
||||
```javascript
|
||||
markers.on('clusterclick', function (a) {
|
||||
var latLngBounds = a.layer.getBounds();
|
||||
});
|
||||
```
|
||||
|
||||
You can also query for the bounding convex polygon.
|
||||
See [example/marker-clustering-convexhull.html](https://leaflet.github.io/Leaflet.markercluster/example/marker-clustering-convexhull.html) for a working example.
|
||||
```javascript
|
||||
markers.on('clusterclick', function (a) {
|
||||
map.addLayer(L.polygon(a.layer.getConvexHull()));
|
||||
});
|
||||
```
|
||||
|
||||
#### Zooming to the bounds of a cluster
|
||||
When you receive an event from a cluster you can zoom to its bounds in one easy step.
|
||||
If all of the markers will appear at a higher zoom level, that zoom level is zoomed to instead.
|
||||
`zoomToBounds` takes an optional argument to pass [options to the resulting `fitBounds` call](http://leafletjs.com/reference.html#map-fitboundsoptions).
|
||||
|
||||
See [marker-clustering-zoomtobounds.html](https://leaflet.github.io/Leaflet.markercluster/example/marker-clustering-zoomtobounds.html) for a working example.
|
||||
```javascript
|
||||
markers.on('clusterclick', function (a) {
|
||||
a.layer.zoomToBounds({padding: [20, 20]});
|
||||
});
|
||||
```
|
||||
|
||||
#### Other clusters methods
|
||||
* **getChildCount**: Returns the total number of markers contained within that cluster.
|
||||
* **getAllChildMarkers(storage: array | undefined, ignoreDraggedMarker: boolean | undefined)**: Returns an array of all markers contained within this cluster (storage will be used if provided). If ignoreDraggedMarker is true and there is currently a marker dragged, the dragged marker will not be included in the array.
|
||||
* **spiderfy**: Spiderfies the child markers of this cluster
|
||||
* **unspiderfy**: Unspiderfies a cluster (opposite of spiderfy)
|
||||
|
||||
## Handling LOTS of markers
|
||||
The Clusterer can handle 10,000 or even 50,000 markers (in chrome). IE9 has some issues with 50,000.
|
||||
- [realworld 10,000 example](https://leaflet.github.io/Leaflet.markercluster/example/marker-clustering-realworld.10000.html)
|
||||
- [realworld 50,000 example](https://leaflet.github.io/Leaflet.markercluster/example/marker-clustering-realworld.50000.html)
|
||||
|
||||
Note: these two examples use the `chunkedLoading` option set to true in order to avoid locking the browser for a long time.
|
||||
|
||||
## License
|
||||
|
||||
Leaflet.markercluster is free software, and may be redistributed under the MIT-LICENSE.
|
||||
|
||||
[](https://travis-ci.org/Leaflet/Leaflet.markercluster)
|
||||
|
||||
## Sub-plugins
|
||||
Leaflet.markercluster plugin is very popular and as such it generates high and
|
||||
diverse expectations for increased functionalities.
|
||||
|
||||
If you are in that case, be sure to have a look first at the repository
|
||||
[issues](https://github.com/Leaflet/Leaflet.markercluster/issues) in case what
|
||||
you are looking for would already be discussed, and some workarounds would be proposed.
|
||||
|
||||
Check also the below sub-plugins:
|
||||
|
||||
| Plugin | Description | Maintainer |
|
||||
| :----- | :---------- | :--------- |
|
||||
| [Leaflet.FeatureGroup.SubGroup](https://github.com/ghybs/Leaflet.FeatureGroup.SubGroup) | Creates a Feature Group that adds its child layers into a parent group when added to a map (e.g. through L.Control.Layers). Typical usage is to dynamically add/remove groups of markers from Marker Cluster. | [ghybs](https://github.com/ghybs) |
|
||||
| [Leaflet.MarkerCluster.LayerSupport](https://github.com/ghybs/Leaflet.MarkerCluster.LayerSupport) | Brings compatibility with L.Control.Layers and other Leaflet plugins. I.e. everything that uses direct calls to map.addLayer and map.removeLayer. | [ghybs](https://github.com/ghybs) |
|
||||
| [Leaflet.MarkerCluster.Freezable](https://github.com/ghybs/Leaflet.MarkerCluster.Freezable) | Adds the ability to freeze clusters at a specified zoom. E.g. freezing at maxZoom + 1 makes as if clustering was programmatically disabled. | [ghybs](https://github.com/ghybs) |
|
||||
| [Leaflet.MarkerCluster.PlacementStrategies](https://github.com/adammertel/Leaflet.MarkerCluster.PlacementStrategies) | Implements new strategies to position clustered markers (eg: clock, concentric circles, ...). Recommended to use with circleMarkers. [Demo](https://adammertel.github.io/Leaflet.MarkerCluster.PlacementStrategies/demo/demo1.html) | [adammertel](https://github.com/adammertel) / [UNIVIE](http://carto.univie.ac.at/) |
|
||||
| [Leaflet.MarkerCluster.List](https://github.com/adammertel/Leaflet.MarkerCluster.List) | Displays child elements in a list. Suitable for mobile devices. [Demo](https://adammertel.github.io/Leaflet.MarkerCluster.List/demo/demo1.html) | [adammertel](https://github.com/adammertel) / [UNIVIE](http://carto.univie.ac.at/) |
|
||||
@@ -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,7 @@
|
||||
{
|
||||
"commitMessage": "version %s",
|
||||
"tagName": "%s",
|
||||
"scripts": {
|
||||
"postcommit": "git push && git push --tags && npm publish"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2011-2015, Pavel Shramov, 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.
|
||||
@@ -0,0 +1,42 @@
|
||||
Leaflet plugins
|
||||
============
|
||||
|
||||
What ?
|
||||
------
|
||||
|
||||
Miscellaneous Leaflet plugins for services that need to display
|
||||
route information and need satellite imagery from different providers.
|
||||
Currently it consists of:
|
||||
|
||||
- Vector layers (`layer/vector/`):
|
||||
* GPX
|
||||
* KML
|
||||
* TOPOJSON
|
||||
|
||||
- Providers implemented with respect to terms of use (`layer/tile`):
|
||||
* [Yandex][Yandex.md] - using Yandex Maps API v2;
|
||||
* [Bing][Bing.md] - with proper attribution.
|
||||
|
||||
- Control (`control/`):
|
||||
* Permalink - OpenLayers compatible permanent link with support for storing location data in hash part (#lat=...);
|
||||
|
||||
[Yandex.md]: https://github.com/shramov/leaflet-plugins/blob/master/layer/tile/Yandex.md
|
||||
[Bing.md]: https://github.com/shramov/leaflet-plugins/blob/master/layer/tile/Bing.md
|
||||
|
||||
|
||||
Compatibility
|
||||
------
|
||||
- Tested with: Leaflet 1.0.x
|
||||
- For use with Leaflet 0.7.x see `v2` branch
|
||||
|
||||
|
||||
Where ?
|
||||
------
|
||||
|
||||
Homepage : https://github.com/shramov/leaflet-plugins
|
||||
|
||||
Downloads : https://github.com/shramov/leaflet-plugins/releases
|
||||
|
||||
npm : https://www.npmjs.org/package/leaflet-plugins
|
||||
|
||||
cdnjs : https://cdnjs.com/libraries/leaflet-plugins
|
||||
@@ -0,0 +1,28 @@
|
||||
JS := $(wildcard ../layer/*/*.js ../layer/*.js ../control/*js)
|
||||
#JS += control/Scale.js control/Distance.js
|
||||
#JS += control/Permalink.js $(wildcard control/Permalink.*.js)
|
||||
JS := $(shell python ./deps.py $(JS))
|
||||
|
||||
#JS_EXTRA := $(JS) $(wildcard layer/*.js)
|
||||
all: compiled.yui.js compiled.closure.js
|
||||
|
||||
compile: $(patsubst %,compiled/%,$(JS))
|
||||
|
||||
closure/%: ../%
|
||||
mkdir -p $(dir $@)
|
||||
java -jar /tmp/closure.jar --compilation_level ADVANCED_OPTIMIZATIONS --charset UTF-8 --js $< --js_output_file $@.tmp
|
||||
mv $@.tmp $@
|
||||
|
||||
yui/%: ../%
|
||||
mkdir -p $(dir $@)
|
||||
yui-compressor --charset UTF-8 -o $@.tmp $<
|
||||
mv $@.tmp $@
|
||||
|
||||
compiled.yui.js: $(patsubst ../%,yui/%,$(JS))
|
||||
compiled.closure.js: $(patsubst ../%,closure/%,$(JS))
|
||||
|
||||
compiled.%.js:
|
||||
for f in $^; do cat $$f >> $@.tmp; echo >> $@.tmp; done
|
||||
mv $@.tmp $@
|
||||
|
||||
.PHONY: all compile
|
||||
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env python
|
||||
# vim: sts=4 sw=4 et
|
||||
|
||||
import os, sys
|
||||
|
||||
printed = set()
|
||||
|
||||
def includes(f):
|
||||
d = os.path.dirname(f)
|
||||
for l in open(f):
|
||||
if l.startswith('//#include'):
|
||||
yield os.path.join(d, l.strip().split(None, 1)[1].strip(""""'"""))
|
||||
|
||||
work = list(sys.argv[1:])
|
||||
|
||||
while work:
|
||||
f = work.pop(0)
|
||||
if f in printed:
|
||||
continue
|
||||
i = list(filter(lambda x: x not in printed, includes(f)))
|
||||
if i:
|
||||
work = i + [f] + work
|
||||
continue
|
||||
printed.add(f)
|
||||
print f
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Add async initialization of layers to L.Control.Layers
|
||||
*/
|
||||
L.Control.Layers.include({
|
||||
_loadScripts: function (scripts, cb, args) {
|
||||
if (!scripts || scripts.length === 0)
|
||||
return cb(args);
|
||||
var _this = this, s = scripts.pop(), c;
|
||||
c = L.Control.Layers._script_cache[s];
|
||||
if (c === undefined) {
|
||||
c = {url: s, wait: []};
|
||||
var script = document.createElement('script');
|
||||
script.src = s;
|
||||
script.type = 'text/javascript';
|
||||
script.onload = function () {
|
||||
var i = 0;
|
||||
for (i = 0; i < c.wait.length; i++)
|
||||
c.wait[i]();
|
||||
};
|
||||
c.e = script;
|
||||
document.getElementsByTagName('head')[0].appendChild(script);
|
||||
}
|
||||
function _cb () { _this._loadScripts(scripts, cb, args); }
|
||||
c.wait.push(_cb);
|
||||
if (c.e.readyState === 'completed')
|
||||
_cb();
|
||||
L.Control.Layers._script_cache[s] = c;
|
||||
},
|
||||
|
||||
addLayerDef: function (name, def) {
|
||||
if (this._layer_defs === undefined)
|
||||
this._layer_defs = {};
|
||||
this._layer_defs[name] = def;
|
||||
},
|
||||
|
||||
addLayerDefs: function (defs) {
|
||||
if (this._layer_defs === undefined)
|
||||
this._layer_defs = {};
|
||||
L.Util.extend(this._layer_defs, defs);
|
||||
},
|
||||
|
||||
loadLayer: function (name, deflt) {
|
||||
var _this = this, l = this._layer_defs[name];
|
||||
l['default'] = deflt;
|
||||
this._loadScripts(l.js.reverse(), function (l) {_this._loadLayer(l);}, l);
|
||||
},
|
||||
|
||||
_loadLayer: function (l) {
|
||||
var x = l.init();
|
||||
if (l['default'] && this._map)
|
||||
this._map.addLayer(x);
|
||||
if (!l.overlay)
|
||||
this.addBaseLayer(x, l.name);
|
||||
else
|
||||
this.addOverlay(x, l.name);
|
||||
}
|
||||
});
|
||||
|
||||
L.Control.Layers._script_cache = {};
|
||||
@@ -0,0 +1,71 @@
|
||||
//#include "Permalink.js
|
||||
|
||||
L.Control.Permalink.include({
|
||||
/*
|
||||
options: {
|
||||
useMarker: true,
|
||||
markerOptions: {}
|
||||
},
|
||||
*/
|
||||
|
||||
initialize_layer: function () {
|
||||
this.on('update', this._set_layer, this);
|
||||
this.on('add', this._onadd_layer, this);
|
||||
},
|
||||
|
||||
_onadd_layer: function () {
|
||||
this._map.on('layeradd', this._update_layer, this);
|
||||
this._map.on('layerremove', this._update_layer, this);
|
||||
this._update_layer();
|
||||
},
|
||||
|
||||
_update_layer: function () {
|
||||
if (!this.options.layers) return;
|
||||
var layer = this.options.layers.currentBaseLayer();
|
||||
if (layer)
|
||||
this._update({layer: layer.name});
|
||||
},
|
||||
|
||||
_set_layer: function (e) {
|
||||
var p = e.params;
|
||||
if (!this.options.layers || !p.layer) return;
|
||||
this.options.layers.chooseBaseLayer(p.layer);
|
||||
}
|
||||
});
|
||||
|
||||
L.Control.Layers.include({
|
||||
chooseBaseLayer: function (name) {
|
||||
var layer, obj;
|
||||
for (var i in this._layers) {
|
||||
if (!this._layers.hasOwnProperty(i))
|
||||
continue;
|
||||
obj = this._layers[i];
|
||||
if (!obj.overlay && obj.name === name)
|
||||
layer = obj.layer;
|
||||
}
|
||||
if (!layer || this._map.hasLayer(layer))
|
||||
return;
|
||||
|
||||
for (var j in this._layers) {
|
||||
if (!this._layers.hasOwnProperty(j))
|
||||
continue;
|
||||
obj = this._layers[j];
|
||||
if (!obj.overlay && this._map.hasLayer(obj.layer))
|
||||
this._map.removeLayer(obj.layer);
|
||||
}
|
||||
this._map.addLayer(layer);
|
||||
this._update();
|
||||
},
|
||||
|
||||
currentBaseLayer: function () {
|
||||
for (var i in this._layers) {
|
||||
if (!this._layers.hasOwnProperty(i))
|
||||
continue;
|
||||
var obj = this._layers[i];
|
||||
if (obj.overlay) continue;
|
||||
if (!obj.overlay && this._map.hasLayer(obj.layer))
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
//#include "Permalink.js
|
||||
|
||||
L.Control.Permalink.include({
|
||||
/*
|
||||
options: {
|
||||
line: null
|
||||
},
|
||||
*/
|
||||
|
||||
initialize_line: function () {
|
||||
this.on('update', this._set_line, this);
|
||||
this.on('add', this._onadd_line, this);
|
||||
},
|
||||
|
||||
_onadd_line: function () {
|
||||
if (!this.options.line) return;
|
||||
this.options.line.on('edit', this._update_line, this);
|
||||
this._update_line();
|
||||
},
|
||||
|
||||
_update_line: function () {
|
||||
if (!this.options.line) return;
|
||||
var line = this.options.line;
|
||||
if (!line) return;
|
||||
var text = [], coords = line.getLatLngs();
|
||||
if (!coords.length)
|
||||
return this._update({line: null});
|
||||
for (var i in coords)
|
||||
text.push(coords[i].lat.toFixed(4) + ',' + coords[i].lng.toFixed(4));
|
||||
this._update({line: text.join(';')});
|
||||
},
|
||||
|
||||
_set_line: function (e) {
|
||||
var p = e.params, l = this.options.line;
|
||||
if (!l || !p.line) return;
|
||||
var coords = [], text = p.line.split(';');
|
||||
for (var i in text) {
|
||||
var ll = text[i].split(',');
|
||||
if (ll.length !== 2) continue;
|
||||
coords.push(new L.LatLng(ll[0], ll[1]));
|
||||
}
|
||||
if (!coords.length) return;
|
||||
l.setLatLngs(coords);
|
||||
if (!this._map.hasLayer(l))
|
||||
this._map.addLayer(l);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,29 @@
|
||||
//#include "Permalink.js
|
||||
|
||||
L.Control.Permalink.include({
|
||||
/*
|
||||
options: {
|
||||
useMarker: true,
|
||||
markerOptions: {}
|
||||
},
|
||||
*/
|
||||
|
||||
initialize_marker: function () {
|
||||
this.on('update', this._set_marker, this);
|
||||
},
|
||||
|
||||
_set_marker: function (e) {
|
||||
var p = e.params;
|
||||
//if (!this.options.useMarker) return;
|
||||
if (this._marker) return;
|
||||
if (p.marker !== 1) return;
|
||||
if (p.mlat !== undefined && p.mlon !== undefined)
|
||||
return this._update({mlat: null, mlon: null,
|
||||
lat: p.mlat, lon: p.mlon, marker: 1});
|
||||
this._marker = new L.Marker(new L.LatLng(p.lat, p.lon),
|
||||
this.options.markerOptions);
|
||||
this._marker.bindPopup('<a href="' + this._update_href() + '">' + this.options.text + '</a>');
|
||||
this._map.addLayer(this._marker);
|
||||
this._update({marker: null});
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,67 @@
|
||||
//#include "Permalink.js
|
||||
|
||||
L.Control.Permalink.include({
|
||||
|
||||
initialize_overlay: function () {
|
||||
this.on('update', this._set_overlays, this);
|
||||
this.on('add', this._onadd_overlay, this);
|
||||
},
|
||||
|
||||
_onadd_overlay: function () {
|
||||
this._map.on('overlayadd', this._update_overlay, this);
|
||||
this._map.on('overlayremove', this._update_overlay, this);
|
||||
this._update_overlay();
|
||||
},
|
||||
|
||||
_update_overlay: function () {
|
||||
if (!this.options.layers) return;
|
||||
var overlayflags = this.options.layers.overlayFlags();
|
||||
if (overlayflags && overlayflags !== '') {
|
||||
this._update({overlays: overlayflags});
|
||||
}
|
||||
},
|
||||
|
||||
_set_overlays: function (e) {
|
||||
var p = e.params;
|
||||
if (!this.options.layers || !p.overlays) return;
|
||||
this.options.layers.setOverlays(p.overlays);
|
||||
}
|
||||
});
|
||||
|
||||
L.Control.Layers.include({
|
||||
setOverlays: function (overlayflags) {
|
||||
var obj, idx=0;
|
||||
for (var i in this._layers) {
|
||||
if (!this._layers.hasOwnProperty(i)) continue;
|
||||
obj = this._layers[i];
|
||||
if (obj.overlay) {
|
||||
// visible if not specified or flag==T
|
||||
var visible = (idx >= overlayflags.length || overlayflags[idx] === 'T');
|
||||
idx++;
|
||||
if (!visible && this._map.hasLayer(obj.layer)) {
|
||||
this._map.removeLayer(obj.layer);
|
||||
} else if (visible && !this._map.hasLayer(obj.layer)) {
|
||||
this._map.addLayer(obj.layer);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
overlayFlags: function () {
|
||||
var flags = '';
|
||||
for (var i in this._layers) {
|
||||
if (!this._layers.hasOwnProperty(i))
|
||||
continue;
|
||||
var obj = this._layers[i];
|
||||
if (!obj.overlay) continue;
|
||||
if (obj.overlay) {
|
||||
if (this._map.hasLayer(obj.layer)) {
|
||||
flags += 'T';
|
||||
} else {
|
||||
flags += 'F';
|
||||
}
|
||||
}
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,177 @@
|
||||
L.Control.Permalink = L.Control.extend({
|
||||
includes: L.Evented ? L.Evented.prototype : L.Mixin.Events,
|
||||
|
||||
options: {
|
||||
position: 'bottomleft',
|
||||
useAnchor: true,
|
||||
useLocation: false,
|
||||
useLocalStorage: false,
|
||||
text: 'Permalink'
|
||||
},
|
||||
|
||||
initialize: function (options) {
|
||||
L.Util.setOptions(this, options);
|
||||
this._params = {};
|
||||
this._set_urlvars();
|
||||
this.on('update', this._set_center, this);
|
||||
for (var i in this) {
|
||||
if (typeof(i) === 'string' && i.indexOf('initialize_') === 0)
|
||||
this[i]();
|
||||
}
|
||||
},
|
||||
|
||||
onAdd: function (map) {
|
||||
this._container = L.DomUtil.create('div', 'leaflet-control-attribution leaflet-control-permalink');
|
||||
L.DomEvent.disableClickPropagation(this._container);
|
||||
this._map = map;
|
||||
this._href = L.DomUtil.create('a', null, this._container);
|
||||
this._href.innerHTML = this.options.text;
|
||||
|
||||
map.on('moveend', this._update_center, this);
|
||||
this.fire('update', {params: this._params});
|
||||
this._update_center();
|
||||
|
||||
if (this.options.useAnchor && 'onhashchange' in window) {
|
||||
var _this = this, fn = window.onhashchange;
|
||||
window.onhashchange = function () {
|
||||
_this._set_urlvars();
|
||||
if (fn) return fn();
|
||||
};
|
||||
}
|
||||
|
||||
this.fire('add', {map: map});
|
||||
|
||||
return this._container;
|
||||
},
|
||||
|
||||
_update_center: function () {
|
||||
if (!this._map) return;
|
||||
|
||||
var center = this._round_point(this._map.getCenter());
|
||||
this._update({zoom: String(this._map.getZoom()), lat: String(center.lat), lon: String(center.lng)});
|
||||
},
|
||||
|
||||
_update_href: function () {
|
||||
var params = L.Util.getParamString(this._params);
|
||||
var sep = '?';
|
||||
if (this.options.useAnchor) sep = '#';
|
||||
var url = this._url_base + sep + params.slice(1);
|
||||
if (this._href) this._href.setAttribute('href', url);
|
||||
if (this.options.useLocation)
|
||||
location.replace('#' + params.slice(1));
|
||||
if (this.options.useLocalStorage)
|
||||
window.localStorage.setItem('paramsTemp', params.slice(1));
|
||||
return url;
|
||||
},
|
||||
|
||||
_round_point : function (point) {
|
||||
var bounds = this._map.getBounds(), size = this._map.getSize();
|
||||
var ne = bounds.getNorthEast(), sw = bounds.getSouthWest();
|
||||
|
||||
var round = function (x, p) {
|
||||
if (p === 0) return x;
|
||||
var shift = 1;
|
||||
while (p < 1 && p > -1) {
|
||||
x *= 10;
|
||||
p *= 10;
|
||||
shift *= 10;
|
||||
}
|
||||
return Math.floor(x)/shift;
|
||||
};
|
||||
point.lat = round(point.lat, (ne.lat - sw.lat) / size.y);
|
||||
point.lng = round(point.lng, (ne.lng - sw.lng) / size.x);
|
||||
return point;
|
||||
},
|
||||
|
||||
_update: function (obj) {
|
||||
for (var i in obj) {
|
||||
if (!obj.hasOwnProperty(i)) continue;
|
||||
if (obj[i] !== null && obj[i] !== undefined)
|
||||
this._params[i] = obj[i];
|
||||
else
|
||||
delete this._params[i];
|
||||
}
|
||||
|
||||
this._update_href();
|
||||
},
|
||||
|
||||
_set_urlvars: function ()
|
||||
{
|
||||
var p;
|
||||
if (this.options.useAnchor) {
|
||||
p = L.UrlUtil.queryParse(L.UrlUtil.hash());
|
||||
this._url_base = window.location.href.split('#')[0];
|
||||
} else {
|
||||
p = L.UrlUtil.queryParse(L.UrlUtil.query());
|
||||
this._url_base = window.location.href.split('#')[0].split('?')[0];
|
||||
}
|
||||
if (this.options.useLocalStorage) {
|
||||
p = window.localStorage.getItem('paramsTemp');
|
||||
if (p !== null) {
|
||||
p = L.UrlUtil.queryParse(p);
|
||||
} else {
|
||||
p = {};
|
||||
}
|
||||
}
|
||||
|
||||
function eq (x, y) {
|
||||
for (var i in x)
|
||||
if (x.hasOwnProperty(i) && x[i] !== y[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (eq(p, this._params) && eq(this._params, p))
|
||||
return;
|
||||
this._params = p;
|
||||
this._update_href();
|
||||
this.fire('update', {params: this._params});
|
||||
},
|
||||
|
||||
_set_center: function (e)
|
||||
{
|
||||
var params = e.params;
|
||||
if (params.zoom === undefined ||
|
||||
params.lat === undefined ||
|
||||
params.lon === undefined) return;
|
||||
this._map.setView(new L.LatLng(params.lat, params.lon), params.zoom);
|
||||
}
|
||||
});
|
||||
|
||||
L.UrlUtil = {
|
||||
queryParse: function (s) {
|
||||
var p = {};
|
||||
var sep = '&';
|
||||
if (s.search('&') !== -1)
|
||||
sep = '&';
|
||||
var params = s.split(sep);
|
||||
for (var i = 0; i < params.length; i++) {
|
||||
var tmp = params[i].split('=');
|
||||
if (tmp.length !== 2) continue;
|
||||
try {
|
||||
p[tmp[0]] = decodeURIComponent(tmp[1]);
|
||||
} catch (e) {
|
||||
p[tmp[0]] = tmp[1];
|
||||
}
|
||||
}
|
||||
return p;
|
||||
},
|
||||
|
||||
query: function () {
|
||||
var href = window.location.href.split('#')[0], idx = href.indexOf('?');
|
||||
if (idx < 0)
|
||||
return '';
|
||||
return href.slice(idx+1);
|
||||
},
|
||||
|
||||
hash: function () { return window.location.hash.slice(1); },
|
||||
|
||||
updateParamString: function (q, obj) {
|
||||
var p = L.UrlUtil.queryParse(q);
|
||||
for (var i in obj) {
|
||||
if (obj.hasOwnProperty(i))
|
||||
p[i] = obj[i];
|
||||
}
|
||||
return L.Util.getParamString(p).slice(1);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,34 @@
|
||||
'use strict'
|
||||
var test = require('tap').test;
|
||||
var fs = require('fs');
|
||||
|
||||
// Hackish
|
||||
GLOBAL.L = {
|
||||
Control: {
|
||||
extend: function () {}
|
||||
},
|
||||
Mixin: {
|
||||
Events: null
|
||||
}
|
||||
}
|
||||
eval(fs.readFileSync('control/Permalink.js').toString());
|
||||
|
||||
|
||||
test('L.UrlUtil.queryParse', function (t) {
|
||||
var data = [
|
||||
['a=1&b=2', {'a': '1', 'b': '2'}],
|
||||
['a=1&b=2', {'a': '1', 'b': '2'}],
|
||||
['a=1,2', {'a': '1,2'}],
|
||||
['a=1%2C2', {'a': '1,2'}],
|
||||
['a=1%2C2&b=3%7C4', {'a': '1,2', 'b': '3|4'}],
|
||||
['name=Лилль', {'name': 'Лилль'}],
|
||||
['name=%D0%9B%D0%B8%D0%BB%D0%BB%D1%8C', {'name': 'Лилль'}],
|
||||
['a=1&name=%D0%9B%D0%B8%D0%BB%D0%BB%D1%8C', {'a': '1', 'name': 'Лилль'}],
|
||||
];
|
||||
data.forEach(function (d) {
|
||||
t.strictSame(L.UrlUtil.queryParse(d[0]), d[1], 'Parsing '+d[0]);
|
||||
});
|
||||
t.plan(data.length, 'Check all parsing tests were done');
|
||||
t.done();
|
||||
})
|
||||
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
@@ -0,0 +1,48 @@
|
||||
.leaflet-control-distance {
|
||||
-moz-border-radius: 7px;
|
||||
-webkit-border-radius: 7px;
|
||||
border-radius: 7px;
|
||||
|
||||
padding: 5px;
|
||||
background-color: rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
|
||||
.leaflet-control-distance a, .leaflet-control-distance div {
|
||||
-moz-border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
|
||||
padding: 2px;
|
||||
background-position: 50% 50%;
|
||||
background-repeat: no-repeat;
|
||||
background-color: rgba(255, 255, 255, 0.75);
|
||||
}
|
||||
|
||||
.leaflet-control-distance a {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.leaflet-control-distance div {
|
||||
font: 11px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
|
||||
color: #333;
|
||||
height: 16px;
|
||||
margin-top: 5px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.leaflet-control-distance-edit {
|
||||
/* http://openclipart.org/detail/114727/ftview-ruler-by-anonymous */
|
||||
background-image: url('measure.png');
|
||||
}
|
||||
|
||||
.leaflet-control-distance-delete {
|
||||
margin-left: 5px;
|
||||
/* Based on http://openclipart.org/detail/34729/architetto----tasto-8-by-anonymous */
|
||||
background-image: url('cross.png');
|
||||
}
|
||||
|
||||
a.leaflet-control-distance-active {
|
||||
background-color: yellow;
|
||||
}
|
||||
|
After Width: | Height: | Size: 470 B |
@@ -0,0 +1,97 @@
|
||||
.osb-popup {
|
||||
font-family: sans-serif;
|
||||
font-size: small;
|
||||
max-width: 380px;
|
||||
overflow: auto;
|
||||
}
|
||||
.osb-popup a:link, .osb-popup a:visited {
|
||||
border-bottom: 1px dotted #C0C0C0;
|
||||
text-decoration: none;
|
||||
}
|
||||
.osb-popup a:link {
|
||||
color: #990000;
|
||||
}
|
||||
.osb-popup a:visited {
|
||||
color: #500000;
|
||||
}
|
||||
.osb-popup a:link:hover, .osb-popup a:visited:hover {
|
||||
border-bottom: 1px solid #C0C0C0;
|
||||
color: red;
|
||||
}
|
||||
.osb-popup a:link:focus .osb-popup a:visited:focus {
|
||||
outline: 1px dotted #C0C0C0;
|
||||
}
|
||||
.osb-popup a:link:active, .osb-popup a:visited:active {
|
||||
border-bottom: 1px solid #F0F0F0;
|
||||
color: red;
|
||||
outline: 1px solid #C0C0C0;
|
||||
}
|
||||
.osb-popup h1 {
|
||||
color: #176BC1;
|
||||
font-size: medium;
|
||||
margin-bottom: 7px;
|
||||
margin-top: 0;
|
||||
}
|
||||
.osb-popup p {
|
||||
margin-bottom: 0;
|
||||
margin-top: 5px;
|
||||
}
|
||||
.osb-popup p.Comment {
|
||||
margin-left: 15px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
.osb-popup p.Note {
|
||||
border-top: 1px solid gray;
|
||||
font-size: x-small;
|
||||
margin-top: 7px;
|
||||
padding-top: 3px;
|
||||
}
|
||||
.osb-popup form + p {
|
||||
border-top: 1px solid gray;
|
||||
margin-top: 15px;
|
||||
padding-top: 10px;
|
||||
}
|
||||
.osb-popup ul {
|
||||
border-top: 1px solid gray;
|
||||
margin: 10px 0 0;
|
||||
padding: 5px 0 0;
|
||||
text-align: center;
|
||||
}
|
||||
.osb-popup ul li {
|
||||
display: inline;
|
||||
margin-left: 12px;
|
||||
margin-right: 12px;
|
||||
padding: 0;
|
||||
}
|
||||
.osb-popup form {
|
||||
margin-bottom: 0;
|
||||
margin-top: 10px;
|
||||
}
|
||||
.osb-popup form.osb-comment {
|
||||
border-top: 1px solid gray;
|
||||
padding-top: 5px;
|
||||
}
|
||||
.osb-popup form div {
|
||||
margin-left: 15px;
|
||||
margin-right: 15px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
.osb-popup form div.osb-footer {
|
||||
margin-bottom: 0;
|
||||
margin-top: 15px;
|
||||
text-align: center;
|
||||
}
|
||||
.osb-popup span.osb-inputlabel {
|
||||
display: inline-block;
|
||||
margin-right: 10px;
|
||||
min-width: 110px;
|
||||
}
|
||||
.osb-popup input[type="text"] {
|
||||
min-width: 190px;
|
||||
}
|
||||
.osb-popup input[type="button"] {
|
||||
margin-left: 3px;
|
||||
margin-right: 3px;
|
||||
min-width: 75px;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,915 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<kml xmlns="http://www.opengis.net/kml/2.2">
|
||||
<Document>
|
||||
<name>KML Samples</name>
|
||||
<open>1</open>
|
||||
<description>Unleash your creativity with the help of these examples!</description>
|
||||
<Style id="downArrowIcon">
|
||||
<IconStyle>
|
||||
<Icon>
|
||||
<href>http://maps.google.com/mapfiles/kml/pal4/icon28.png</href>
|
||||
</Icon>
|
||||
</IconStyle>
|
||||
</Style>
|
||||
<Style id="globeIcon">
|
||||
<IconStyle>
|
||||
<Icon>
|
||||
<href>http://maps.google.com/mapfiles/kml/pal3/icon19.png</href>
|
||||
</Icon>
|
||||
</IconStyle>
|
||||
<LineStyle>
|
||||
<width>2</width>
|
||||
</LineStyle>
|
||||
</Style>
|
||||
<Style id="transPurpleLineGreenPoly">
|
||||
<LineStyle>
|
||||
<color>7fff00ff</color>
|
||||
<width>4</width>
|
||||
</LineStyle>
|
||||
<PolyStyle>
|
||||
<color>7f00ff00</color>
|
||||
</PolyStyle>
|
||||
</Style>
|
||||
<Style id="yellowLineGreenPoly">
|
||||
<LineStyle>
|
||||
<color>7f00ffff</color>
|
||||
<width>4</width>
|
||||
</LineStyle>
|
||||
<PolyStyle>
|
||||
<color>7f00ff00</color>
|
||||
</PolyStyle>
|
||||
</Style>
|
||||
<Style id="thickBlackLine">
|
||||
<LineStyle>
|
||||
<color>87000000</color>
|
||||
<width>10</width>
|
||||
</LineStyle>
|
||||
</Style>
|
||||
<Style id="redLineBluePoly">
|
||||
<LineStyle>
|
||||
<color>ff0000ff</color>
|
||||
</LineStyle>
|
||||
<PolyStyle>
|
||||
<color>ffff0000</color>
|
||||
</PolyStyle>
|
||||
</Style>
|
||||
<Style id="blueLineRedPoly">
|
||||
<LineStyle>
|
||||
<color>ffff0000</color>
|
||||
</LineStyle>
|
||||
<PolyStyle>
|
||||
<color>ff0000ff</color>
|
||||
</PolyStyle>
|
||||
</Style>
|
||||
<Style id="transRedPoly">
|
||||
<LineStyle>
|
||||
<width>1.5</width>
|
||||
</LineStyle>
|
||||
<PolyStyle>
|
||||
<color>7d0000ff</color>
|
||||
</PolyStyle>
|
||||
</Style>
|
||||
<Style id="transBluePoly">
|
||||
<LineStyle>
|
||||
<width>1.5</width>
|
||||
</LineStyle>
|
||||
<PolyStyle>
|
||||
<color>7dff0000</color>
|
||||
</PolyStyle>
|
||||
</Style>
|
||||
<Style id="transGreenPoly">
|
||||
<LineStyle>
|
||||
<width>1.5</width>
|
||||
</LineStyle>
|
||||
<PolyStyle>
|
||||
<color>7d00ff00</color>
|
||||
</PolyStyle>
|
||||
</Style>
|
||||
<Style id="transYellowPoly">
|
||||
<LineStyle>
|
||||
<width>1.5</width>
|
||||
</LineStyle>
|
||||
<PolyStyle>
|
||||
<color>7d00ffff</color>
|
||||
</PolyStyle>
|
||||
</Style>
|
||||
<Style id="noDrivingDirections">
|
||||
<BalloonStyle>
|
||||
<text><![CDATA[
|
||||
<b>$[name]</b>
|
||||
<br /><br />
|
||||
$[description]
|
||||
]]></text>
|
||||
</BalloonStyle>
|
||||
</Style>
|
||||
<Folder>
|
||||
<name>Placemarks</name>
|
||||
<description>These are just some of the different kinds of placemarks with
|
||||
which you can mark your favorite places</description>
|
||||
<LookAt>
|
||||
<longitude>-122.0839597145766</longitude>
|
||||
<latitude>37.42222904525232</latitude>
|
||||
<altitude>0</altitude>
|
||||
<heading>-148.4122922628044</heading>
|
||||
<tilt>40.5575073395506</tilt>
|
||||
<range>500.6566641072245</range>
|
||||
</LookAt>
|
||||
<Placemark>
|
||||
<name>Simple placemark</name>
|
||||
<description>Attached to the ground. Intelligently places itself at the
|
||||
height of the underlying terrain.</description>
|
||||
<Point>
|
||||
<coordinates>-122.0822035425683,37.42228990140251,0</coordinates>
|
||||
</Point>
|
||||
</Placemark>
|
||||
<Placemark>
|
||||
<name>Floating placemark</name>
|
||||
<visibility>0</visibility>
|
||||
<description>Floats a defined distance above the ground.</description>
|
||||
<LookAt>
|
||||
<longitude>-122.0839597145766</longitude>
|
||||
<latitude>37.42222904525232</latitude>
|
||||
<altitude>0</altitude>
|
||||
<heading>-148.4122922628044</heading>
|
||||
<tilt>40.5575073395506</tilt>
|
||||
<range>500.6566641072245</range>
|
||||
</LookAt>
|
||||
<styleUrl>#downArrowIcon</styleUrl>
|
||||
<Point>
|
||||
<altitudeMode>relativeToGround</altitudeMode>
|
||||
<coordinates>-122.084075,37.4220033612141,50</coordinates>
|
||||
</Point>
|
||||
</Placemark>
|
||||
<Placemark>
|
||||
<name>Extruded placemark</name>
|
||||
<visibility>0</visibility>
|
||||
<description>Tethered to the ground by a customizable
|
||||
"tail"</description>
|
||||
<LookAt>
|
||||
<longitude>-122.0845787421525</longitude>
|
||||
<latitude>37.42215078737763</latitude>
|
||||
<altitude>0</altitude>
|
||||
<heading>-148.4126684946234</heading>
|
||||
<tilt>40.55750733918048</tilt>
|
||||
<range>365.2646606980322</range>
|
||||
</LookAt>
|
||||
<styleUrl>#globeIcon</styleUrl>
|
||||
<Point>
|
||||
<extrude>1</extrude>
|
||||
<altitudeMode>relativeToGround</altitudeMode>
|
||||
<coordinates>-122.0857667006183,37.42156927867553,50</coordinates>
|
||||
</Point>
|
||||
</Placemark>
|
||||
</Folder>
|
||||
<Folder>
|
||||
<name>Styles and Markup</name>
|
||||
<visibility>0</visibility>
|
||||
<description>With KML it is easy to create rich, descriptive markup to
|
||||
annotate and enrich your placemarks</description>
|
||||
<LookAt>
|
||||
<longitude>-122.0845787422371</longitude>
|
||||
<latitude>37.42215078726837</latitude>
|
||||
<altitude>0</altitude>
|
||||
<heading>-148.4126777488172</heading>
|
||||
<tilt>40.55750733930874</tilt>
|
||||
<range>365.2646826292919</range>
|
||||
</LookAt>
|
||||
<styleUrl>#noDrivingDirections</styleUrl>
|
||||
<Document>
|
||||
<name>Highlighted Icon</name>
|
||||
<visibility>0</visibility>
|
||||
<description>Place your mouse over the icon to see it display the new
|
||||
icon</description>
|
||||
<LookAt>
|
||||
<longitude>-122.0856552124024</longitude>
|
||||
<latitude>37.4224281311035</latitude>
|
||||
<altitude>0</altitude>
|
||||
<heading>0</heading>
|
||||
<tilt>0</tilt>
|
||||
<range>265.8520424250024</range>
|
||||
</LookAt>
|
||||
<Style id="highlightPlacemark">
|
||||
<IconStyle>
|
||||
<Icon>
|
||||
<href>http://maps.google.com/mapfiles/kml/paddle/red-stars.png</href>
|
||||
</Icon>
|
||||
</IconStyle>
|
||||
</Style>
|
||||
<Style id="normalPlacemark">
|
||||
<IconStyle>
|
||||
<Icon>
|
||||
<href>http://maps.google.com/mapfiles/kml/paddle/wht-blank.png</href>
|
||||
</Icon>
|
||||
</IconStyle>
|
||||
</Style>
|
||||
<StyleMap id="exampleStyleMap">
|
||||
<Pair>
|
||||
<key>normal</key>
|
||||
<styleUrl>#normalPlacemark</styleUrl>
|
||||
</Pair>
|
||||
<Pair>
|
||||
<key>highlight</key>
|
||||
<styleUrl>#highlightPlacemark</styleUrl>
|
||||
</Pair>
|
||||
</StyleMap>
|
||||
<Placemark>
|
||||
<name>Roll over this icon</name>
|
||||
<visibility>0</visibility>
|
||||
<styleUrl>#exampleStyleMap</styleUrl>
|
||||
<Point>
|
||||
<coordinates>-122.0856545755255,37.42243077405461,0</coordinates>
|
||||
</Point>
|
||||
</Placemark>
|
||||
</Document>
|
||||
<Placemark>
|
||||
<name>Descriptive HTML</name>
|
||||
<visibility>0</visibility>
|
||||
<description><![CDATA[Click on the blue link!<br><br>
|
||||
Placemark descriptions can be enriched by using many standard HTML tags.<br>
|
||||
For example:
|
||||
<hr>
|
||||
Styles:<br>
|
||||
<i>Italics</i>,
|
||||
<b>Bold</b>,
|
||||
<u>Underlined</u>,
|
||||
<s>Strike Out</s>,
|
||||
subscript<sub>subscript</sub>,
|
||||
superscript<sup>superscript</sup>,
|
||||
<big>Big</big>,
|
||||
<small>Small</small>,
|
||||
<tt>Typewriter</tt>,
|
||||
<em>Emphasized</em>,
|
||||
<strong>Strong</strong>,
|
||||
<code>Code</code>
|
||||
<hr>
|
||||
Fonts:<br>
|
||||
<font color="red">red by name</font>,
|
||||
<font color="#408010">leaf green by hexadecimal RGB</font>
|
||||
<br>
|
||||
<font size=1>size 1</font>,
|
||||
<font size=2>size 2</font>,
|
||||
<font size=3>size 3</font>,
|
||||
<font size=4>size 4</font>,
|
||||
<font size=5>size 5</font>,
|
||||
<font size=6>size 6</font>,
|
||||
<font size=7>size 7</font>
|
||||
<br>
|
||||
<font face=times>Times</font>,
|
||||
<font face=verdana>Verdana</font>,
|
||||
<font face=arial>Arial</font><br>
|
||||
<hr>
|
||||
Links:
|
||||
<br>
|
||||
<a href="http://earth.google.com/">Google Earth!</a>
|
||||
<br>
|
||||
or: Check out our website at www.google.com
|
||||
<hr>
|
||||
Alignment:<br>
|
||||
<p align=left>left</p>
|
||||
<p align=center>center</p>
|
||||
<p align=right>right</p>
|
||||
<hr>
|
||||
Ordered Lists:<br>
|
||||
<ol><li>First</li><li>Second</li><li>Third</li></ol>
|
||||
<ol type="a"><li>First</li><li>Second</li><li>Third</li></ol>
|
||||
<ol type="A"><li>First</li><li>Second</li><li>Third</li></ol>
|
||||
<hr>
|
||||
Unordered Lists:<br>
|
||||
<ul><li>A</li><li>B</li><li>C</li></ul>
|
||||
<ul type="circle"><li>A</li><li>B</li><li>C</li></ul>
|
||||
<ul type="square"><li>A</li><li>B</li><li>C</li></ul>
|
||||
<hr>
|
||||
Definitions:<br>
|
||||
<dl>
|
||||
<dt>Google:</dt><dd>The best thing since sliced bread</dd>
|
||||
</dl>
|
||||
<hr>
|
||||
Centered:<br><center>
|
||||
Time present and time past<br>
|
||||
Are both perhaps present in time future,<br>
|
||||
And time future contained in time past.<br>
|
||||
If all time is eternally present<br>
|
||||
All time is unredeemable.<br>
|
||||
</center>
|
||||
<hr>
|
||||
Block Quote:
|
||||
<br>
|
||||
<blockquote>
|
||||
We shall not cease from exploration<br>
|
||||
And the end of all our exploring<br>
|
||||
Will be to arrive where we started<br>
|
||||
And know the place for the first time.<br>
|
||||
<i>-- T.S. Eliot</i>
|
||||
</blockquote>
|
||||
<br>
|
||||
<hr>
|
||||
Headings:<br>
|
||||
<h1>Header 1</h1>
|
||||
<h2>Header 2</h2>
|
||||
<h3>Header 3</h3>
|
||||
<h3>Header 4</h4>
|
||||
<h3>Header 5</h5>
|
||||
<hr>
|
||||
Images:<br>
|
||||
<i>Remote image</i><br>
|
||||
<img src="//developers.google.com/kml/documentation/images/googleSample.png"><br>
|
||||
<i>Scaled image</i><br>
|
||||
<img src="//developers.google.com/kml/documentation/images/googleSample.png" width=100><br>
|
||||
<hr>
|
||||
Simple Tables:<br>
|
||||
<table border="1" padding="1">
|
||||
<tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
|
||||
<tr><td>a</td><td>b</td><td>c</td><td>d</td><td>e</td></tr>
|
||||
</table>
|
||||
<br>
|
||||
[Did you notice that double-clicking on the placemark doesn't cause the viewer to take you anywhere? This is because it is possible to directly author a "placeless placemark". If you look at the code for this example, you will see that it has neither a point coordinate nor a LookAt element.]]]></description>
|
||||
</Placemark>
|
||||
</Folder>
|
||||
<Folder>
|
||||
<name>Ground Overlays</name>
|
||||
<visibility>0</visibility>
|
||||
<description>Examples of ground overlays</description>
|
||||
<GroundOverlay>
|
||||
<name>Large-scale overlay on terrain</name>
|
||||
<visibility>0</visibility>
|
||||
<description>Overlay shows Mount Etna erupting on July 13th, 2001.</description>
|
||||
<LookAt>
|
||||
<longitude>15.02468937557116</longitude>
|
||||
<latitude>37.67395167941667</latitude>
|
||||
<altitude>0</altitude>
|
||||
<heading>-16.5581842842829</heading>
|
||||
<tilt>58.31228652890705</tilt>
|
||||
<range>30350.36838438907</range>
|
||||
</LookAt>
|
||||
<Icon>
|
||||
<href>http://developers.google.com/kml/documentation/images/etna.jpg</href>
|
||||
</Icon>
|
||||
<LatLonBox>
|
||||
<north>37.91904192681665</north>
|
||||
<south>37.46543388598137</south>
|
||||
<east>15.35832653742206</east>
|
||||
<west>14.60128369746704</west>
|
||||
<rotation>-0.1556640799496235</rotation>
|
||||
</LatLonBox>
|
||||
</GroundOverlay>
|
||||
</Folder>
|
||||
<Folder>
|
||||
<name>Screen Overlays</name>
|
||||
<visibility>0</visibility>
|
||||
<description>Screen overlays have to be authored directly in KML. These
|
||||
examples illustrate absolute and dynamic positioning in screen space.</description>
|
||||
<ScreenOverlay>
|
||||
<name>Simple crosshairs</name>
|
||||
<visibility>0</visibility>
|
||||
<description>This screen overlay uses fractional positioning to put the
|
||||
image in the exact center of the screen</description>
|
||||
<Icon>
|
||||
<href>http://developers.google.com/kml/documentation/images/crosshairs.png</href>
|
||||
</Icon>
|
||||
<overlayXY x="0.5" y="0.5" xunits="fraction" yunits="fraction"/>
|
||||
<screenXY x="0.5" y="0.5" xunits="fraction" yunits="fraction"/>
|
||||
<rotationXY x="0.5" y="0.5" xunits="fraction" yunits="fraction"/>
|
||||
<size x="0" y="0" xunits="pixels" yunits="pixels"/>
|
||||
</ScreenOverlay>
|
||||
<ScreenOverlay>
|
||||
<name>Absolute Positioning: Top left</name>
|
||||
<visibility>0</visibility>
|
||||
<Icon>
|
||||
<href>http://developers.google.com/kml/documentation/images/top_left.jpg</href>
|
||||
</Icon>
|
||||
<overlayXY x="0" y="1" xunits="fraction" yunits="fraction"/>
|
||||
<screenXY x="0" y="1" xunits="fraction" yunits="fraction"/>
|
||||
<rotationXY x="0" y="0" xunits="fraction" yunits="fraction"/>
|
||||
<size x="0" y="0" xunits="fraction" yunits="fraction"/>
|
||||
</ScreenOverlay>
|
||||
<ScreenOverlay>
|
||||
<name>Absolute Positioning: Top right</name>
|
||||
<visibility>0</visibility>
|
||||
<Icon>
|
||||
<href>http://developers.google.com/kml/documentation/images/top_right.jpg</href>
|
||||
</Icon>
|
||||
<overlayXY x="1" y="1" xunits="fraction" yunits="fraction"/>
|
||||
<screenXY x="1" y="1" xunits="fraction" yunits="fraction"/>
|
||||
<rotationXY x="0" y="0" xunits="fraction" yunits="fraction"/>
|
||||
<size x="0" y="0" xunits="fraction" yunits="fraction"/>
|
||||
</ScreenOverlay>
|
||||
<ScreenOverlay>
|
||||
<name>Absolute Positioning: Bottom left</name>
|
||||
<visibility>0</visibility>
|
||||
<Icon>
|
||||
<href>http://developers.google.com/kml/documentation/images/bottom_left.jpg</href>
|
||||
</Icon>
|
||||
<overlayXY x="0" y="-1" xunits="fraction" yunits="fraction"/>
|
||||
<screenXY x="0" y="0" xunits="fraction" yunits="fraction"/>
|
||||
<rotationXY x="0" y="0" xunits="fraction" yunits="fraction"/>
|
||||
<size x="0" y="0" xunits="fraction" yunits="fraction"/>
|
||||
</ScreenOverlay>
|
||||
<ScreenOverlay>
|
||||
<name>Absolute Positioning: Bottom right</name>
|
||||
<visibility>0</visibility>
|
||||
<Icon>
|
||||
<href>http://developers.google.com/kml/documentation/images/bottom_right.jpg</href>
|
||||
</Icon>
|
||||
<overlayXY x="1" y="-1" xunits="fraction" yunits="fraction"/>
|
||||
<screenXY x="1" y="0" xunits="fraction" yunits="fraction"/>
|
||||
<rotationXY x="0" y="0" xunits="fraction" yunits="fraction"/>
|
||||
<size x="0" y="0" xunits="fraction" yunits="fraction"/>
|
||||
</ScreenOverlay>
|
||||
<ScreenOverlay>
|
||||
<name>Dynamic Positioning: Top of screen</name>
|
||||
<visibility>0</visibility>
|
||||
<Icon>
|
||||
<href>http://developers.google.com/kml/documentation/images/dynamic_screenoverlay.jpg</href>
|
||||
</Icon>
|
||||
<overlayXY x="0" y="1" xunits="fraction" yunits="fraction"/>
|
||||
<screenXY x="0" y="1" xunits="fraction" yunits="fraction"/>
|
||||
<rotationXY x="0" y="0" xunits="fraction" yunits="fraction"/>
|
||||
<size x="1" y="0.2" xunits="fraction" yunits="fraction"/>
|
||||
</ScreenOverlay>
|
||||
<ScreenOverlay>
|
||||
<name>Dynamic Positioning: Right of screen</name>
|
||||
<visibility>0</visibility>
|
||||
<Icon>
|
||||
<href>http://developers.google.com/kml/documentation/images/dynamic_right.jpg</href>
|
||||
</Icon>
|
||||
<overlayXY x="1" y="1" xunits="fraction" yunits="fraction"/>
|
||||
<screenXY x="1" y="1" xunits="fraction" yunits="fraction"/>
|
||||
<rotationXY x="0" y="0" xunits="fraction" yunits="fraction"/>
|
||||
<size x="0" y="1" xunits="fraction" yunits="fraction"/>
|
||||
</ScreenOverlay>
|
||||
</Folder>
|
||||
<Folder>
|
||||
<name>Paths</name>
|
||||
<visibility>0</visibility>
|
||||
<description>Examples of paths. Note that the tessellate tag is by default
|
||||
set to 0. If you want to create tessellated lines, they must be authored
|
||||
(or edited) directly in KML.</description>
|
||||
<Placemark>
|
||||
<name>Tessellated</name>
|
||||
<visibility>0</visibility>
|
||||
<description><![CDATA[If the <tessellate> tag has a value of 1, the line will contour to the underlying terrain]]></description>
|
||||
<LookAt>
|
||||
<longitude>-112.0822680013139</longitude>
|
||||
<latitude>36.09825589333556</latitude>
|
||||
<altitude>0</altitude>
|
||||
<heading>103.8120432044965</heading>
|
||||
<tilt>62.04855796276328</tilt>
|
||||
<range>2889.145007690472</range>
|
||||
</LookAt>
|
||||
<LineString>
|
||||
<tessellate>1</tessellate>
|
||||
<coordinates> -112.0814237830345,36.10677870477137,0
|
||||
-112.0870267752693,36.0905099328766,0 </coordinates>
|
||||
</LineString>
|
||||
</Placemark>
|
||||
<Placemark>
|
||||
<name>Untessellated</name>
|
||||
<visibility>0</visibility>
|
||||
<description><![CDATA[If the <tessellate> tag has a value of 0, the line follow a simple straight-line path from point to point]]></description>
|
||||
<LookAt>
|
||||
<longitude>-112.0822680013139</longitude>
|
||||
<latitude>36.09825589333556</latitude>
|
||||
<altitude>0</altitude>
|
||||
<heading>103.8120432044965</heading>
|
||||
<tilt>62.04855796276328</tilt>
|
||||
<range>2889.145007690472</range>
|
||||
</LookAt>
|
||||
<LineString>
|
||||
<tessellate>0</tessellate>
|
||||
<coordinates> -112.080622229595,36.10673460007995,0
|
||||
-112.085242575315,36.09049598612422,0 </coordinates>
|
||||
</LineString>
|
||||
</Placemark>
|
||||
<Placemark>
|
||||
<name>Absolute</name>
|
||||
<visibility>0</visibility>
|
||||
<description>Transparent purple line</description>
|
||||
<LookAt>
|
||||
<longitude>-112.2719329043177</longitude>
|
||||
<latitude>36.08890633450894</latitude>
|
||||
<altitude>0</altitude>
|
||||
<heading>-106.8161545998597</heading>
|
||||
<tilt>44.60763714063257</tilt>
|
||||
<range>2569.386744398339</range>
|
||||
</LookAt>
|
||||
<styleUrl>#transPurpleLineGreenPoly</styleUrl>
|
||||
<LineString>
|
||||
<tessellate>1</tessellate>
|
||||
<altitudeMode>absolute</altitudeMode>
|
||||
<coordinates> -112.265654928602,36.09447672602546,2357
|
||||
-112.2660384528238,36.09342608838671,2357
|
||||
-112.2668139013453,36.09251058776881,2357
|
||||
-112.2677826834445,36.09189827357996,2357
|
||||
-112.2688557510952,36.0913137941187,2357
|
||||
-112.2694810717219,36.0903677207521,2357
|
||||
-112.2695268555611,36.08932171487285,2357
|
||||
-112.2690144567276,36.08850916060472,2357
|
||||
-112.2681528815339,36.08753813597956,2357
|
||||
-112.2670588176031,36.08682685262568,2357
|
||||
-112.2657374587321,36.08646312301303,2357 </coordinates>
|
||||
</LineString>
|
||||
</Placemark>
|
||||
<Placemark>
|
||||
<name>Absolute Extruded</name>
|
||||
<visibility>0</visibility>
|
||||
<description>Transparent green wall with yellow outlines</description>
|
||||
<LookAt>
|
||||
<longitude>-112.2643334742529</longitude>
|
||||
<latitude>36.08563154742419</latitude>
|
||||
<altitude>0</altitude>
|
||||
<heading>-125.7518698668815</heading>
|
||||
<tilt>44.61038665812578</tilt>
|
||||
<range>4451.842204068102</range>
|
||||
</LookAt>
|
||||
<styleUrl>#yellowLineGreenPoly</styleUrl>
|
||||
<LineString>
|
||||
<extrude>1</extrude>
|
||||
<tessellate>1</tessellate>
|
||||
<altitudeMode>absolute</altitudeMode>
|
||||
<coordinates> -112.2550785337791,36.07954952145647,2357
|
||||
-112.2549277039738,36.08117083492122,2357
|
||||
-112.2552505069063,36.08260761307279,2357
|
||||
-112.2564540158376,36.08395660588506,2357
|
||||
-112.2580238976449,36.08511401044813,2357
|
||||
-112.2595218489022,36.08584355239394,2357
|
||||
-112.2608216347552,36.08612634548589,2357
|
||||
-112.262073428656,36.08626019085147,2357
|
||||
-112.2633204928495,36.08621519860091,2357
|
||||
-112.2644963846444,36.08627897945274,2357
|
||||
-112.2656969554589,36.08649599090644,2357 </coordinates>
|
||||
</LineString>
|
||||
</Placemark>
|
||||
<Placemark>
|
||||
<name>Relative</name>
|
||||
<visibility>0</visibility>
|
||||
<description>Black line (10 pixels wide), height tracks terrain</description>
|
||||
<LookAt>
|
||||
<longitude>-112.2580438551384</longitude>
|
||||
<latitude>36.1072674824385</latitude>
|
||||
<altitude>0</altitude>
|
||||
<heading>4.947421249553717</heading>
|
||||
<tilt>44.61324882043339</tilt>
|
||||
<range>2927.61105910266</range>
|
||||
</LookAt>
|
||||
<styleUrl>#thickBlackLine</styleUrl>
|
||||
<LineString>
|
||||
<tessellate>1</tessellate>
|
||||
<altitudeMode>relativeToGround</altitudeMode>
|
||||
<coordinates> -112.2532845153347,36.09886943729116,645
|
||||
-112.2540466121145,36.09919570465255,645
|
||||
-112.254734666947,36.09984998366178,645
|
||||
-112.255493345654,36.10051310621746,645
|
||||
-112.2563157098468,36.10108441943419,645
|
||||
-112.2568033076439,36.10159722088088,645
|
||||
-112.257494011321,36.10204323542867,645
|
||||
-112.2584106072308,36.10229131995655,645
|
||||
-112.2596588987972,36.10240001286358,645
|
||||
-112.2610581199487,36.10213176873407,645
|
||||
-112.2626285262793,36.10157011437219,645 </coordinates>
|
||||
</LineString>
|
||||
</Placemark>
|
||||
<Placemark>
|
||||
<name>Relative Extruded</name>
|
||||
<visibility>0</visibility>
|
||||
<description>Opaque blue walls with red outline, height tracks terrain</description>
|
||||
<LookAt>
|
||||
<longitude>-112.2683594333433</longitude>
|
||||
<latitude>36.09884362144909</latitude>
|
||||
<altitude>0</altitude>
|
||||
<heading>-72.24271551768405</heading>
|
||||
<tilt>44.60855445139561</tilt>
|
||||
<range>2184.193522571467</range>
|
||||
</LookAt>
|
||||
<styleUrl>#redLineBluePoly</styleUrl>
|
||||
<LineString>
|
||||
<extrude>1</extrude>
|
||||
<tessellate>1</tessellate>
|
||||
<altitudeMode>relativeToGround</altitudeMode>
|
||||
<coordinates> -112.2656634181359,36.09445214722695,630
|
||||
-112.2652238941097,36.09520916122063,630
|
||||
-112.2645079986395,36.09580763864907,630
|
||||
-112.2638827428817,36.09628572284063,630
|
||||
-112.2635746835406,36.09679275951239,630
|
||||
-112.2635711822407,36.09740038871899,630
|
||||
-112.2640296531825,36.09804913435539,630
|
||||
-112.264327720538,36.09880337400301,630
|
||||
-112.2642436562271,36.09963644790288,630
|
||||
-112.2639148687042,36.10055381117246,630
|
||||
-112.2626894973474,36.10149062823369,630 </coordinates>
|
||||
</LineString>
|
||||
</Placemark>
|
||||
</Folder>
|
||||
<Folder>
|
||||
<name>Polygons</name>
|
||||
<visibility>0</visibility>
|
||||
<description>Examples of polygon shapes</description>
|
||||
<Folder>
|
||||
<name>Google Campus</name>
|
||||
<visibility>0</visibility>
|
||||
<description>A collection showing how easy it is to create 3-dimensional
|
||||
buildings</description>
|
||||
<LookAt>
|
||||
<longitude>-122.084120030116</longitude>
|
||||
<latitude>37.42174011925477</latitude>
|
||||
<altitude>0</altitude>
|
||||
<heading>-34.82469740081282</heading>
|
||||
<tilt>53.454348562403</tilt>
|
||||
<range>276.7870053764046</range>
|
||||
</LookAt>
|
||||
<Placemark>
|
||||
<name>Building 40</name>
|
||||
<visibility>0</visibility>
|
||||
<styleUrl>#transRedPoly</styleUrl>
|
||||
<Polygon>
|
||||
<extrude>1</extrude>
|
||||
<altitudeMode>relativeToGround</altitudeMode>
|
||||
<outerBoundaryIs>
|
||||
<LinearRing>
|
||||
<coordinates> -122.0848938459612,37.42257124044786,17
|
||||
-122.0849580979198,37.42211922626856,17
|
||||
-122.0847469573047,37.42207183952619,17
|
||||
-122.0845725380962,37.42209006729676,17
|
||||
-122.0845954886723,37.42215932700895,17
|
||||
-122.0838521118269,37.42227278564371,17
|
||||
-122.083792243335,37.42203539112084,17
|
||||
-122.0835076656616,37.42209006957106,17
|
||||
-122.0834709464152,37.42200987395161,17
|
||||
-122.0831221085748,37.4221046494946,17
|
||||
-122.0829247374572,37.42226503990386,17
|
||||
-122.0829339169385,37.42231242843094,17
|
||||
-122.0833837359737,37.42225046087618,17
|
||||
-122.0833607854248,37.42234159228745,17
|
||||
-122.0834204551642,37.42237075460644,17
|
||||
-122.083659133885,37.42251292011001,17
|
||||
-122.0839758438952,37.42265873093781,17
|
||||
-122.0842374743331,37.42265143972521,17
|
||||
-122.0845036949503,37.4226514386435,17
|
||||
-122.0848020460801,37.42261133916315,17
|
||||
-122.0847882750515,37.42256395055121,17
|
||||
-122.0848938459612,37.42257124044786,17 </coordinates>
|
||||
</LinearRing>
|
||||
</outerBoundaryIs>
|
||||
</Polygon>
|
||||
</Placemark>
|
||||
<Placemark>
|
||||
<name>Building 41</name>
|
||||
<visibility>0</visibility>
|
||||
<styleUrl>#transBluePoly</styleUrl>
|
||||
<Polygon>
|
||||
<extrude>1</extrude>
|
||||
<altitudeMode>relativeToGround</altitudeMode>
|
||||
<outerBoundaryIs>
|
||||
<LinearRing>
|
||||
<coordinates> -122.0857412771483,37.42227033155257,17
|
||||
-122.0858169768481,37.42231408832346,17
|
||||
-122.085852582875,37.42230337469744,17
|
||||
-122.0858799945639,37.42225686138789,17
|
||||
-122.0858860101409,37.4222311076138,17
|
||||
-122.0858069157288,37.42220250173855,17
|
||||
-122.0858379542653,37.42214027058678,17
|
||||
-122.0856732640519,37.42208690214408,17
|
||||
-122.0856022926407,37.42214885429042,17
|
||||
-122.0855902778436,37.422128290487,17
|
||||
-122.0855841672237,37.42208171967246,17
|
||||
-122.0854852065741,37.42210455874995,17
|
||||
-122.0855067264352,37.42214267949824,17
|
||||
-122.0854430712915,37.42212783846172,17
|
||||
-122.0850990714904,37.42251282407603,17
|
||||
-122.0856769818632,37.42281815323651,17
|
||||
-122.0860162273783,37.42244918858722,17
|
||||
-122.0857260327004,37.42229239604253,17
|
||||
-122.0857412771483,37.42227033155257,17 </coordinates>
|
||||
</LinearRing>
|
||||
</outerBoundaryIs>
|
||||
</Polygon>
|
||||
</Placemark>
|
||||
<Placemark>
|
||||
<name>Building 42</name>
|
||||
<visibility>0</visibility>
|
||||
<styleUrl>#transGreenPoly</styleUrl>
|
||||
<Polygon>
|
||||
<extrude>1</extrude>
|
||||
<altitudeMode>relativeToGround</altitudeMode>
|
||||
<outerBoundaryIs>
|
||||
<LinearRing>
|
||||
<coordinates> -122.0857862287242,37.42136208886969,25
|
||||
-122.0857312990603,37.42136935989481,25
|
||||
-122.0857312992918,37.42140934910903,25
|
||||
-122.0856077073679,37.42138390166565,25
|
||||
-122.0855802426516,37.42137299550869,25
|
||||
-122.0852186221971,37.42137299504316,25
|
||||
-122.0852277765639,37.42161656508265,25
|
||||
-122.0852598189347,37.42160565894403,25
|
||||
-122.0852598185499,37.42168200156,25
|
||||
-122.0852369311478,37.42170017860346,25
|
||||
-122.0852643957828,37.42176197982575,25
|
||||
-122.0853239032746,37.42176198013907,25
|
||||
-122.0853559454324,37.421852864452,25
|
||||
-122.0854108752463,37.42188921823734,25
|
||||
-122.0854795379357,37.42189285337048,25
|
||||
-122.0855436229819,37.42188921797546,25
|
||||
-122.0856260178042,37.42186013499926,25
|
||||
-122.085937287963,37.42186013453605,25
|
||||
-122.0859428718666,37.42160898590042,25
|
||||
-122.0859655469861,37.42157992759144,25
|
||||
-122.0858640462341,37.42147115002957,25
|
||||
-122.0858548911215,37.42140571326184,25
|
||||
-122.0858091162768,37.4214057134039,25
|
||||
-122.0857862287242,37.42136208886969,25 </coordinates>
|
||||
</LinearRing>
|
||||
</outerBoundaryIs>
|
||||
</Polygon>
|
||||
</Placemark>
|
||||
<Placemark>
|
||||
<name>Building 43</name>
|
||||
<visibility>0</visibility>
|
||||
<styleUrl>#transYellowPoly</styleUrl>
|
||||
<Polygon>
|
||||
<extrude>1</extrude>
|
||||
<altitudeMode>relativeToGround</altitudeMode>
|
||||
<outerBoundaryIs>
|
||||
<LinearRing>
|
||||
<coordinates> -122.0844371128284,37.42177253003091,19
|
||||
-122.0845118855746,37.42191111542896,19
|
||||
-122.0850470999805,37.42178755121535,19
|
||||
-122.0850719913391,37.42143663023161,19
|
||||
-122.084916406232,37.42137237822116,19
|
||||
-122.0842193868167,37.42137237801626,19
|
||||
-122.08421938659,37.42147617161496,19
|
||||
-122.0838086419991,37.4214613409357,19
|
||||
-122.0837899728564,37.42131306410796,19
|
||||
-122.0832796534698,37.42129328840593,19
|
||||
-122.0832609819207,37.42139213944298,19
|
||||
-122.0829373621737,37.42137236399876,19
|
||||
-122.0829062425667,37.42151569778871,19
|
||||
-122.0828502269665,37.42176282576465,19
|
||||
-122.0829435788635,37.42176776969635,19
|
||||
-122.083217411188,37.42179248552686,19
|
||||
-122.0835970430103,37.4217480074456,19
|
||||
-122.0839455556771,37.42169364237603,19
|
||||
-122.0840077894637,37.42176283815853,19
|
||||
-122.084113587521,37.42174801104392,19
|
||||
-122.0840762473784,37.42171341292375,19
|
||||
-122.0841447047739,37.42167881534569,19
|
||||
-122.084144704223,37.42181720660197,19
|
||||
-122.0842503333074,37.4218170700446,19
|
||||
-122.0844371128284,37.42177253003091,19 </coordinates>
|
||||
</LinearRing>
|
||||
</outerBoundaryIs>
|
||||
</Polygon>
|
||||
</Placemark>
|
||||
</Folder>
|
||||
<Folder>
|
||||
<name>Extruded Polygon</name>
|
||||
<description>A simple way to model a building</description>
|
||||
<Placemark>
|
||||
<name>The Pentagon</name>
|
||||
<LookAt>
|
||||
<longitude>-77.05580139178142</longitude>
|
||||
<latitude>38.870832443487</latitude>
|
||||
<heading>59.88865561738225</heading>
|
||||
<tilt>48.09646074797388</tilt>
|
||||
<range>742.0552506670548</range>
|
||||
</LookAt>
|
||||
<Polygon>
|
||||
<extrude>1</extrude>
|
||||
<altitudeMode>relativeToGround</altitudeMode>
|
||||
<outerBoundaryIs>
|
||||
<LinearRing>
|
||||
<coordinates> -77.05788457660967,38.87253259892824,100
|
||||
-77.05465973756702,38.87291016281703,100
|
||||
-77.05315536854791,38.87053267794386,100
|
||||
-77.05552622493516,38.868757801256,100
|
||||
-77.05844056290393,38.86996206506943,100
|
||||
-77.05788457660967,38.87253259892824,100 </coordinates>
|
||||
</LinearRing>
|
||||
</outerBoundaryIs>
|
||||
<innerBoundaryIs>
|
||||
<LinearRing>
|
||||
<coordinates> -77.05668055019126,38.87154239798456,100
|
||||
-77.05542625960818,38.87167890344077,100
|
||||
-77.05485125901024,38.87076535397792,100
|
||||
-77.05577677433152,38.87008686581446,100
|
||||
-77.05691162017543,38.87054446963351,100
|
||||
-77.05668055019126,38.87154239798456,100 </coordinates>
|
||||
</LinearRing>
|
||||
</innerBoundaryIs>
|
||||
</Polygon>
|
||||
</Placemark>
|
||||
</Folder>
|
||||
<Folder>
|
||||
<name>Absolute and Relative</name>
|
||||
<visibility>0</visibility>
|
||||
<description>Four structures whose roofs meet exactly. Turn on/off
|
||||
terrain to see the difference between relative and absolute
|
||||
positioning.</description>
|
||||
<LookAt>
|
||||
<longitude>-112.3348969157552</longitude>
|
||||
<latitude>36.14845533214919</latitude>
|
||||
<altitude>0</altitude>
|
||||
<heading>-86.91235037566909</heading>
|
||||
<tilt>49.30695423894192</tilt>
|
||||
<range>990.6761201087104</range>
|
||||
</LookAt>
|
||||
<Placemark>
|
||||
<name>Absolute</name>
|
||||
<visibility>0</visibility>
|
||||
<styleUrl>#transBluePoly</styleUrl>
|
||||
<Polygon>
|
||||
<tessellate>1</tessellate>
|
||||
<altitudeMode>absolute</altitudeMode>
|
||||
<outerBoundaryIs>
|
||||
<LinearRing>
|
||||
<coordinates> -112.3372510731295,36.14888505105317,1784
|
||||
-112.3356128688403,36.14781540589019,1784
|
||||
-112.3368169371048,36.14658677734382,1784
|
||||
-112.3384408457543,36.14762778914076,1784
|
||||
-112.3372510731295,36.14888505105317,1784 </coordinates>
|
||||
</LinearRing>
|
||||
</outerBoundaryIs>
|
||||
</Polygon>
|
||||
</Placemark>
|
||||
<Placemark>
|
||||
<name>Absolute Extruded</name>
|
||||
<visibility>0</visibility>
|
||||
<styleUrl>#transRedPoly</styleUrl>
|
||||
<Polygon>
|
||||
<extrude>1</extrude>
|
||||
<tessellate>1</tessellate>
|
||||
<altitudeMode>absolute</altitudeMode>
|
||||
<outerBoundaryIs>
|
||||
<LinearRing>
|
||||
<coordinates> -112.3396586818843,36.14637618647505,1784
|
||||
-112.3380597654315,36.14531751871353,1784
|
||||
-112.3368254237788,36.14659596244607,1784
|
||||
-112.3384555043203,36.14762621763982,1784
|
||||
-112.3396586818843,36.14637618647505,1784 </coordinates>
|
||||
</LinearRing>
|
||||
</outerBoundaryIs>
|
||||
</Polygon>
|
||||
</Placemark>
|
||||
<Placemark>
|
||||
<name>Relative</name>
|
||||
<visibility>0</visibility>
|
||||
<LookAt>
|
||||
<longitude>-112.3350152490417</longitude>
|
||||
<latitude>36.14943123077423</latitude>
|
||||
<altitude>0</altitude>
|
||||
<heading>-118.9214100848499</heading>
|
||||
<tilt>37.92486261093203</tilt>
|
||||
<range>345.5169113679813</range>
|
||||
</LookAt>
|
||||
<styleUrl>#transGreenPoly</styleUrl>
|
||||
<Polygon>
|
||||
<tessellate>1</tessellate>
|
||||
<altitudeMode>relativeToGround</altitudeMode>
|
||||
<outerBoundaryIs>
|
||||
<LinearRing>
|
||||
<coordinates> -112.3349463145932,36.14988705767721,100
|
||||
-112.3354019540677,36.14941108398372,100
|
||||
-112.3344428289146,36.14878490381308,100
|
||||
-112.3331289492913,36.14780840132443,100
|
||||
-112.3317019516947,36.14680755678357,100
|
||||
-112.331131440106,36.1474173426228,100
|
||||
-112.332616324338,36.14845453364654,100
|
||||
-112.3339876620524,36.14926570522069,100
|
||||
-112.3349463145932,36.14988705767721,100 </coordinates>
|
||||
</LinearRing>
|
||||
</outerBoundaryIs>
|
||||
</Polygon>
|
||||
</Placemark>
|
||||
<Placemark>
|
||||
<name>Relative Extruded</name>
|
||||
<visibility>0</visibility>
|
||||
<LookAt>
|
||||
<longitude>-112.3351587892382</longitude>
|
||||
<latitude>36.14979247129029</latitude>
|
||||
<altitude>0</altitude>
|
||||
<heading>-55.42811560891606</heading>
|
||||
<tilt>56.10280503739589</tilt>
|
||||
<range>401.0997279712519</range>
|
||||
</LookAt>
|
||||
<styleUrl>#transYellowPoly</styleUrl>
|
||||
<Polygon>
|
||||
<extrude>1</extrude>
|
||||
<tessellate>1</tessellate>
|
||||
<altitudeMode>relativeToGround</altitudeMode>
|
||||
<outerBoundaryIs>
|
||||
<LinearRing>
|
||||
<coordinates> -112.3348783983763,36.1514008468736,100
|
||||
-112.3372535345629,36.14888517553886,100
|
||||
-112.3356068927954,36.14781612679284,100
|
||||
-112.3350034807972,36.14846469024177,100
|
||||
-112.3358353861232,36.1489624162954,100
|
||||
-112.3345888301373,36.15026229372507,100
|
||||
-112.3337937856278,36.14978096026463,100
|
||||
-112.3331798208424,36.1504472788618,100
|
||||
-112.3348783983763,36.1514008468736,100 </coordinates>
|
||||
</LinearRing>
|
||||
</outerBoundaryIs>
|
||||
</Polygon>
|
||||
</Placemark>
|
||||
</Folder>
|
||||
</Folder>
|
||||
</Document>
|
||||
</kml>
|
||||
@@ -0,0 +1,55 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Leaflet</title>
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css" />
|
||||
<script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"></script>
|
||||
<script src="../layer/tile/Bing.js"></script>
|
||||
<script src="../layer/tile/Bing.addon.applyMaxNativeZoom.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div style="width:100%; height:100%" id="map"></div>
|
||||
|
||||
<script type='text/javascript'>
|
||||
var map = L.map('map', {
|
||||
center: [67.6755, 33.936],
|
||||
zoom: 10
|
||||
});
|
||||
var apiKey = '[YOUR_BING_MAPS_KEY]';
|
||||
|
||||
var defaults = {
|
||||
key: apiKey,
|
||||
detectRetina: true
|
||||
};
|
||||
var baseLayers = {};
|
||||
[ 'Aerial', 'AerialWithLabelsOnDemand',
|
||||
'RoadOnDemand',
|
||||
'CanvasDark', 'CanvasLight', 'CanvasGray'
|
||||
].forEach(function (imagerySet) {
|
||||
baseLayers[imagerySet] = L.bingLayer(L.extend({imagerySet: imagerySet}, defaults));
|
||||
});
|
||||
|
||||
// https://docs.microsoft.com/en-us/bingmaps/articles/custom-map-styles-in-bing-maps#midnight-commander-style
|
||||
var styleMidnightCommander = 'me|lbc:ffffff;loc:000000_pl|bsc:144b53;boc:00000000_pt|ic:0c4152;fc:000000;sc:0c4152_trs|sc:000000;fc:000000_hg|sc:158399;fc:000000_cah|sc:158399;fc:000000_ard|sc:157399;fc:000000_mr|sc:157399;fc:000000_rl|sc:146474;fc:000000_str|fc:115166_wt|fc:021019_ar|fc:115166_g|lc:0b334d';
|
||||
baseLayers['Custom style + "ru" culture'] = L.bingLayer(L.extend({}, defaults, {
|
||||
imagerySet: 'RoadOnDemand',
|
||||
style: styleMidnightCommander,
|
||||
culture: 'ru'
|
||||
}));
|
||||
|
||||
baseLayers['[deprecated] Road'] = L.bingLayer(L.extend({}, defaults, {
|
||||
imagerySet: 'Road',
|
||||
retinaDpi: false
|
||||
}));
|
||||
baseLayers['[deprecated] AerialWithLabels'] = L.bingLayer(L.extend({}, defaults, {
|
||||
imagerySet: 'AerialWithLabels',
|
||||
retinaDpi: false
|
||||
}));
|
||||
|
||||
baseLayers['RoadOnDemand'].addTo(map);
|
||||
L.control.layers(baseLayers).addTo(map);
|
||||
map.locate({ setView: true, maxZoom: 14 });
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,63 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Leaflet</title>
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css" />
|
||||
<script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"></script>
|
||||
<!--script src="https://api-maps.yandex.ru/2.1/?lang=en_RU&apikey=<your API-key>" type="text/javascript"></script-->
|
||||
<script src="../layer/Layer.Deferred.js"></script>
|
||||
<!--<script src="../layer/tile/Yandex.js"></script>-->
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div style="width:100%; height:100%" id="map"></div>
|
||||
<script>
|
||||
var map = L.map('map', {center: [67.6755, 33.936], zoom: 10});
|
||||
|
||||
map.attributionControl
|
||||
.setPosition('bottomleft')
|
||||
.setPrefix('');
|
||||
|
||||
function traffic () {
|
||||
// https://tech.yandex.ru/maps/jsbox/2.1/traffic_provider
|
||||
var actualProvider = new ymaps.traffic.provider.Actual({}, { infoLayerShown: true });
|
||||
actualProvider.setMap(this._yandex);
|
||||
}
|
||||
var ymapsAPI = 'https://api-maps.yandex.ru/2.1/?lang=en_RU&apikey=<your API-key>';
|
||||
var mapsurferUrl = 'https://maps.heigit.org/openmapsurfer/tiles/hybrid/webmercator/{z}/{x}/{y}.png';
|
||||
|
||||
var layerdefs = {
|
||||
ysat: {
|
||||
name: 'Yandex',
|
||||
js: ['../layer/tile/Yandex.js', ymapsAPI],
|
||||
init: function () { return L.yandex('satellite'); }
|
||||
},
|
||||
traffic: {
|
||||
name: 'Traffic',
|
||||
js: ['../layer/tile/Yandex.js', ymapsAPI],
|
||||
init: function () { return L.yandex('overlay').on('load',traffic); }
|
||||
},
|
||||
mso: {
|
||||
name: 'Mapsurfer',
|
||||
js: [], overlay: true,
|
||||
init: function() { return L.tileLayer(mapsurferUrl, {pane:'overlayPane'}); }
|
||||
}
|
||||
};
|
||||
|
||||
var baseLayers = {
|
||||
'OSM': L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png')
|
||||
.addTo(map),
|
||||
'Yandex': new L.DeferredLayer(layerdefs.ysat)
|
||||
};
|
||||
|
||||
var overlays = {
|
||||
'Traffic': new L.DeferredLayer(layerdefs.traffic),
|
||||
'OpenMapSurfer': new L.DeferredLayer(layerdefs.mso)
|
||||
};
|
||||
|
||||
L.control.layers(baseLayers,overlays).addTo(map);
|
||||
|
||||
map.locate({ setView: true, maxZoom: 14 });
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,9 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Leaflet Control Distance</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>See <a href="https://github.com/jacobtoye/Leaflet.measure">Leaflet.measure</a> or
|
||||
<a href="https://github.com/makinacorpus/Leaflet.MeasureControl">Leaflet.MeasureControl</a></p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,10 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Google // Leaflet</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<p>See <a href="https://gitlab.com/IvanSanchez/Leaflet.GridLayer.GoogleMutant">Leaflet.GridLayer.GoogleMutant</a></p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,25 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Leaflet - GPX track without Waypoints</title>
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css" />
|
||||
<script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"></script>
|
||||
<script src="../layer/vector/GPX.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div style="width:100%; height:100%" id="map"></div>
|
||||
|
||||
<script type='text/javascript'>
|
||||
var map = L.map('map', {center: L.latLng(58.4, 43.0), zoom: 11});
|
||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
|
||||
var track = new L.GPX('fells_loop.gpx', {
|
||||
async: true,
|
||||
display_wpt:false
|
||||
}).on('loaded', function (e) {
|
||||
map.fitBounds(e.target.getBounds());
|
||||
}).addTo(map);
|
||||
L.control.layers({}, {'GPX':track}).addTo(map);
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,28 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Leaflet</title>
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css" />
|
||||
<script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"></script>
|
||||
<script src="../layer/vector/GPX.js"></script>
|
||||
<script src="../layer/vector/GPX.Speed.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div style="width:100%; height:100%" id="map"></div>
|
||||
|
||||
<script type='text/javascript'>
|
||||
var map = L.map('map', {center: L.latLng(58.4, 43.0), zoom: 11});
|
||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
|
||||
var track = new L.GPX('speed.gpx', {
|
||||
async: true
|
||||
}).on('loaded', function (e) {
|
||||
map.fitBounds(e.target.getBounds());
|
||||
}).speedSplitEnable({
|
||||
maxSpeed: 100,
|
||||
chunks: 1000
|
||||
}).addTo(map);
|
||||
L.control.layers({}, {'GPX':track}).addTo(map);
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,39 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Leaflet</title>
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css" />
|
||||
<script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"></script>
|
||||
<script src="../layer/vector/GPX.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div style="width:100%; height:100%" id="map"></div>
|
||||
|
||||
<script type='text/javascript'>
|
||||
var map = L.map('map', {center: L.latLng(58.4, 43.0), zoom: 11});
|
||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
|
||||
var greenIcon = L.icon({
|
||||
// from https://leafletjs.com/examples/custom-icons.html
|
||||
iconUrl: 'https://leafletjs.com/examples/custom-icons/leaf-green.png',
|
||||
shadowUrl: 'https://leafletjs.com/examples/custom-icons/leaf-shadow.png',
|
||||
iconSize: [38, 95],
|
||||
shadowSize: [50, 64],
|
||||
iconAnchor: [22, 94],
|
||||
shadowAnchor: [4, 62],
|
||||
popupAnchor: [-3, -76]
|
||||
});
|
||||
var track = new L.GPX('fells_loop.gpx', {
|
||||
async: true
|
||||
}).on('loaded', function (e) {
|
||||
map.fitBounds(e.target.getBounds());
|
||||
}).on('addpoint', function (args) {
|
||||
// set greemIcon for all point with 'Gate' in description
|
||||
if (args.attributes.desc.indexOf('Gate') !== -1) {
|
||||
args.point.setIcon(greenIcon);
|
||||
}
|
||||
}).addTo(map);
|
||||
L.control.layers({}, {'GPX':track}).addTo(map);
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,24 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Leaflet</title>
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css" />
|
||||
<script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"></script>
|
||||
<script src="../layer/vector/KML.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div style="width:100%; height:100%" id="map"></div>
|
||||
|
||||
<script type='text/javascript'>
|
||||
var map = L.map('map', {center: L.latLng(58.4, 43.0), zoom: 11});
|
||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
|
||||
var track = new L.KML('KML_Samples.kml', {async: true})
|
||||
.on('loaded', function (e) {
|
||||
map.fitBounds(e.target.getBounds());
|
||||
})
|
||||
.addTo(map);
|
||||
L.control.layers({}, {'Track':track}).addTo(map);
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,36 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Leaflet</title>
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css" />
|
||||
<script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"></script>
|
||||
<script src="../layer/Icon.Canvas.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div style="width:100%; height:100%" id="map"></div>
|
||||
|
||||
<script type='text/javascript'>
|
||||
var center = [67.6755, 33.936];
|
||||
var map = L.map('map', {center: center, zoom: 10});
|
||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
|
||||
var circle = new L.Icon.Canvas({iconSize: L.point(30, 30)});
|
||||
circle.draw = function (ctx, w, h) {
|
||||
ctx.translate(w/2, h/2);
|
||||
ctx.beginPath();
|
||||
ctx.fillStyle = '#F00';
|
||||
ctx.arc(0, 0, w/2-1, 0, Math.PI*2, true);
|
||||
ctx.fill();
|
||||
ctx.lineWidth = 2;
|
||||
ctx.strokeStyle = '#FFF';
|
||||
ctx.moveTo(-w/5, -h/5);
|
||||
ctx.lineTo(w/5, h/5);
|
||||
ctx.moveTo(-w/5, h/5);
|
||||
ctx.lineTo(w/5, -h/5);
|
||||
ctx.stroke();
|
||||
ctx.closePath();
|
||||
};
|
||||
L.marker(center, {icon: circle, draggable: true, opacity: 0.7}).addTo(map);
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,34 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Leaflet</title>
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css" />
|
||||
<style>
|
||||
/* Animates marker movements */
|
||||
.leaflet-marker-pane > *,
|
||||
.leaflet-shadow-pane > * {
|
||||
transition: transform 1.0s linear;
|
||||
}
|
||||
</style>
|
||||
<script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet-src.js"></script>
|
||||
<script src="../layer/Marker.Rotate.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div style="width:100%; height:100%" id="map"></div>
|
||||
|
||||
<script type='text/javascript'>
|
||||
var center = [67.6755, 33.936];
|
||||
var map = L.map('map', {center: center, zoom: 10});
|
||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
|
||||
var marker = L.marker(center, {iconAngle: 90}).addTo(map);
|
||||
var angle = 0;
|
||||
function _rotate () {
|
||||
marker.setIconAngle(angle);
|
||||
angle = (angle + 10) % 360;
|
||||
setTimeout(_rotate, 1000);
|
||||
}
|
||||
_rotate();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,21 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Leaflet</title>
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css" />
|
||||
<script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"></script>
|
||||
<script src="../layer/Marker.Text.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div style="width:100%; height:100%" id="map"></div>
|
||||
|
||||
<script type='text/javascript'>
|
||||
var center = [67.6755, 33.936];
|
||||
var map = L.map('map', {center: center, zoom: 10});
|
||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
|
||||
var marker = new L.Marker.Text(map.getCenter(), 'Sweet and nowrap!');
|
||||
map.addLayer(marker);
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,22 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Leaflet</title>
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css" />
|
||||
<script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"></script>
|
||||
<script src="../layer/vector/OSM.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div style="width:100%; height:100%" id="map"></div>
|
||||
|
||||
<script type='text/javascript'>
|
||||
var map = L.map('map', { center: L.latLng(55.7, 37.6), zoom: 9, zoomAnimation: false});
|
||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
|
||||
var layer = new L.OSM('test.osm').on('loaded', function (e) {
|
||||
map.fitBounds(e.target.getBounds());
|
||||
}).addTo(map);
|
||||
L.control.layers({}, {'OSM':layer}).addTo(map);
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,34 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Leaflet</title>
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css" />
|
||||
<script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"></script>
|
||||
<script src="../control/Permalink.js"></script>
|
||||
<script src="../control/Permalink.Marker.js"></script>
|
||||
<script src="../control/Permalink.Layer.js"></script>
|
||||
<script src="../control/Permalink.Overlay.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div style="width:100%; height:100%" id="map"></div>
|
||||
|
||||
<script type='text/javascript'>
|
||||
var map = L.map('map', {center: L.latLng(47.93, -3.44), zoom: 7});
|
||||
var osm = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');
|
||||
var appid = '9de243494c0b295cca9337e1e96b00e2'; // demo id
|
||||
var pressure = L.tileLayer('https://{s}.tile.openweathermap.org/map/pressure_cntr/{z}/{x}/{y}.png?appid='+appid, {
|
||||
maxZoom: 19,
|
||||
attribution: 'Map data © <a href="https://openweathermap.org">OpenWeatherMap</a>',
|
||||
opacity: 0.5
|
||||
});
|
||||
var hydda = L.tileLayer('https://{s}.tile.openstreetmap.se/hydda/full/{z}/{x}/{y}.png', {
|
||||
attribution: 'Tiles courtesy of <a href="https://openstreetmap.se/" target="_blank">OpenStreetMap Sweden</a> — Map data © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>'
|
||||
});
|
||||
var layers = L.control.layers({'OSM':osm, 'Hydda':hydda},{'Pressure':pressure});
|
||||
map.addLayer(osm);
|
||||
map.addControl(layers);
|
||||
map.addControl(new L.Control.Permalink({text: 'Permalink', layers: layers}));
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,518 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<osm version='0.6' generator='JOSM'>
|
||||
<node id='-638' action='modify' visible='true' lat='53.97457427063642' lon='58.42229228635642'>
|
||||
<tag k='addr:housenumber' v='110' />
|
||||
<tag k='addr:street' v='улица Карла Маркса' />
|
||||
<tag k='source:addr' v='extrapolation' />
|
||||
</node>
|
||||
<node id='-633' action='modify' visible='true' lat='53.97746211393457' lon='58.4235326840818'>
|
||||
<tag k='addr:housenumber' v='107' />
|
||||
<tag k='addr:street' v='улица Ленина' />
|
||||
<tag k='source:addr' v='extrapolation' />
|
||||
</node>
|
||||
<node id='-630' action='modify' visible='true' lat='53.97455917685295' lon='58.419640401564216'>
|
||||
<tag k='addr:housenumber' v='17' />
|
||||
<tag k='addr:street' v='улица Димитрова' />
|
||||
<tag k='source:addr' v='extrapolation' />
|
||||
</node>
|
||||
<node id='-625' action='modify' visible='true' lat='53.975288703465914' lon='58.419948362378804'>
|
||||
<tag k='addr:housenumber' v='16' />
|
||||
<tag k='addr:street' v='улица Димитрова' />
|
||||
<tag k='source:addr' v='extrapolation' />
|
||||
</node>
|
||||
<node id='-623' action='modify' visible='true' lat='53.97514279916518' lon='58.420239214259226'>
|
||||
<tag k='addr:housenumber' v='18' />
|
||||
<tag k='addr:street' v='улица Димитрова' />
|
||||
<tag k='source:addr' v='extrapolation' />
|
||||
</node>
|
||||
<node id='-620' action='modify' visible='true' lat='53.975565417115654' lon='58.419469312222795'>
|
||||
<tag k='addr:housenumber' v='12' />
|
||||
<tag k='addr:street' v='улица Димитрова' />
|
||||
<tag k='source:addr' v='extrapolation' />
|
||||
</node>
|
||||
<node id='-611' action='modify' visible='true' lat='53.9742120183242' lon='58.420204996390964'>
|
||||
<tag k='addr:housenumber' v='21' />
|
||||
<tag k='addr:street' v='улица Димитрова' />
|
||||
<tag k='source:addr' v='extrapolation' />
|
||||
</node>
|
||||
<node id='-607' action='modify' visible='true' lat='53.9746950207073' lon='58.41940087648624'>
|
||||
<tag k='addr:housenumber' v='15' />
|
||||
<tag k='addr:street' v='улица Димитрова' />
|
||||
<tag k='source:addr' v='extrapolation' />
|
||||
</node>
|
||||
<node id='-605' action='modify' visible='true' lat='53.97589384288913' lon='58.41694010845963'>
|
||||
<tag k='addr:housenumber' v='93' />
|
||||
<tag k='addr:street' v='улица Ленина' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-603' action='modify' visible='true' lat='53.97605687494371' lon='58.41728991615893'>
|
||||
<tag k='addr:housenumber' v='95' />
|
||||
<tag k='addr:street' v='улица Ленина' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-601' action='modify' visible='true' lat='53.97522100071186' lon='58.4168593733863'>
|
||||
<tag k='addr:housenumber' v='16' />
|
||||
<tag k='addr:street' v='улица Крупской' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-599' action='modify' visible='true' lat='53.975551148353105' lon='58.41799429516045'>
|
||||
<tag k='addr:housenumber' v='3' />
|
||||
<tag k='addr:street' v='улица Димитрова' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-597' action='modify' visible='true' lat='53.97480797328408' lon='58.41751900499705'>
|
||||
<tag k='addr:housenumber' v='24' />
|
||||
<tag k='addr:street' v='улица Крупской' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-595' action='modify' visible='true' lat='53.97760885982362' lon='58.42377110493086'>
|
||||
<tag k='addr:housenumber' v='109' />
|
||||
<tag k='addr:street' v='улица Ленина' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-593' action='modify' visible='true' lat='53.97439319274232' lon='58.419908755274434'>
|
||||
<tag k='addr:housenumber' v='19' />
|
||||
<tag k='addr:street' v='улица Димитрова' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-591' action='modify' visible='true' lat='53.97390055653927' lon='58.41896818547377'>
|
||||
<tag k='addr:housenumber' v='36' />
|
||||
<tag k='addr:street' v='улица Крупской' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-589' action='modify' visible='true' lat='53.97683920829169' lon='58.425041110772874'>
|
||||
<tag k='addr:housenumber' v='9' />
|
||||
<tag k='addr:street' v='Кооперативная улица' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-587' action='modify' visible='true' lat='53.97405720148785' lon='58.420428871655325'>
|
||||
<tag k='addr:housenumber' v='23' />
|
||||
<tag k='addr:street' v='улица Димитрова' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-585' action='modify' visible='true' lat='53.97359853207158' lon='58.41945052350913'>
|
||||
<tag k='addr:housenumber' v='40' />
|
||||
<tag k='addr:street' v='улица Крупской' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-583' action='modify' visible='true' lat='53.973473765869485' lon='58.419649776162586'>
|
||||
<tag k='addr:housenumber' v='42' />
|
||||
<tag k='addr:street' v='улица Крупской' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-581' action='modify' visible='true' lat='53.973548314425315' lon='58.42033867996988'>
|
||||
<tag k='addr:housenumber' v='102' />
|
||||
<tag k='addr:street' v='улица Карла Маркса' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-579' action='modify' visible='true' lat='53.9744657456174' lon='58.42202485669254'>
|
||||
<tag k='addr:housenumber' v='108' />
|
||||
<tag k='addr:street' v='улица Карла Маркса' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-577' action='modify' visible='true' lat='53.97470600558978' lon='58.42245287466258'>
|
||||
<tag k='addr:housenumber' v='112' />
|
||||
<tag k='addr:street' v='улица Карла Маркса' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-575' action='modify' visible='true' lat='53.97502915893774' lon='58.42194552386521'>
|
||||
<tag k='addr:housenumber' v='23' />
|
||||
<tag k='addr:street' v='улица Гафури' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-573' action='modify' visible='true' lat='53.974690463132255' lon='58.420943706174576'>
|
||||
<tag k='addr:housenumber' v='24' />
|
||||
<tag k='addr:street' v='улица Димитрова' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-571' action='modify' visible='true' lat='53.974961887017514' lon='58.42048682245521'>
|
||||
<tag k='addr:housenumber' v='20' />
|
||||
<tag k='addr:street' v='улица Димитрова' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-569' action='modify' visible='true' lat='53.975754357449254' lon='58.42076114194038'>
|
||||
<tag k='addr:housenumber' v='13' />
|
||||
<tag k='addr:street' v='улица Гафури' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-567' action='modify' visible='true' lat='53.97540565700766' lon='58.41973982473407'>
|
||||
<tag k='addr:housenumber' v='14' />
|
||||
<tag k='addr:street' v='улица Димитрова' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-565' action='modify' visible='true' lat='53.97617692723762' lon='58.420070998614136'>
|
||||
<tag k='addr:housenumber' v='7' />
|
||||
<tag k='addr:street' v='улица Гафури' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-563' action='modify' visible='true' lat='53.97584985943758' lon='58.41899209111958'>
|
||||
<tag k='addr:housenumber' v='8' />
|
||||
<tag k='addr:street' v='улица Димитрова' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-561' action='modify' visible='true' lat='53.97598998486164' lon='58.41875621392154'>
|
||||
<tag k='addr:housenumber' v='6' />
|
||||
<tag k='addr:street' v='улица Димитрова' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-559' action='modify' visible='true' lat='53.976123525721555' lon='58.41853141997336'>
|
||||
<tag k='addr:housenumber' v='4' />
|
||||
<tag k='addr:street' v='улица Димитрова' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-557' action='modify' visible='true' lat='53.97671331033789' lon='58.421043917427326'>
|
||||
<tag k='addr:housenumber' v='2' />
|
||||
<tag k='addr:street' v='улица Гафури' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-555' action='modify' visible='true' lat='53.97615492209121' lon='58.421933514296455'>
|
||||
<tag k='addr:housenumber' v='10' />
|
||||
<tag k='addr:street' v='улица Гафури' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-553' action='modify' visible='true' lat='53.97600216561641' lon='58.42339651259624'>
|
||||
<tag k='addr:housenumber' v='15' />
|
||||
<tag k='addr:street' v='улица Дзержинского' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-551' action='modify' visible='true' lat='53.97546244959517' lon='58.42303671107927'>
|
||||
<tag k='addr:housenumber' v='20' />
|
||||
<tag k='addr:street' v='улица Гафури' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-549' action='modify' visible='true' lat='53.97535681971057' lon='58.423204991311984'>
|
||||
<tag k='addr:housenumber' v='22' />
|
||||
<tag k='addr:street' v='улица Гафури' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-547' action='modify' visible='true' lat='53.97607407176052' lon='58.42467063017959'>
|
||||
<tag k='addr:housenumber' v='120' />
|
||||
<tag k='addr:street' v='улица Карла Маркса' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-545' action='modify' visible='true' lat='53.976691890025286' lon='58.42528419870593'>
|
||||
<tag k='addr:housenumber' v='11' />
|
||||
<tag k='addr:street' v='Кооперативная улица' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-541' action='modify' visible='true' lat='53.9773105359524' lon='58.423232306195516'>
|
||||
<tag k='addr:housenumber' v='105' />
|
||||
<tag k='addr:street' v='улица Ленина' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-539' action='modify' visible='true' lat='53.97516907828648' lon='58.42171701155993'>
|
||||
<tag k='addr:housenumber' v='21' />
|
||||
<tag k='addr:street' v='улица Гафури' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-537' action='modify' visible='true' lat='53.975381619830486' lon='58.416602852462574'>
|
||||
<tag k='addr:housenumber' v='14/а' />
|
||||
<tag k='addr:street' v='улица Крупской' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-535' action='modify' visible='true' lat='53.974862395999644' lon='58.42065429452581'>
|
||||
<tag k='addr:housenumber' v='20а' />
|
||||
<tag k='addr:street' v='улица Димитрова' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-533' action='modify' visible='true' lat='53.976647038217145' lon='58.422346637112085'>
|
||||
<tag k='addr:housenumber' v='7' />
|
||||
<tag k='addr:street' v='улица Дзержинского' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-531' action='modify' visible='true' lat='53.97646243843631' lon='58.418183669062586'>
|
||||
<tag k='addr:housenumber' v='2б' />
|
||||
<tag k='addr:street' v='улица Димитрова' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-529' action='modify' visible='true' lat='53.97480875964128' lon='58.41920412293308'>
|
||||
<tag k='addr:housenumber' v='13' />
|
||||
<tag k='addr:street' v='улица Димитрова' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-527' action='modify' visible='true' lat='53.97380268168014' lon='58.42084363536258'>
|
||||
<tag k='addr:housenumber' v='106' />
|
||||
<tag k='addr:street' v='улица Карла Маркса' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-525' action='modify' visible='true' lat='53.97395475574385' lon='58.42059581683141'>
|
||||
<tag k='addr:housenumber' v='25' />
|
||||
<tag k='addr:street' v='улица Димитрова' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-523' action='modify' visible='true' lat='53.97479170464607' lon='58.420773288214185'>
|
||||
<tag k='addr:housenumber' v='22' />
|
||||
<tag k='addr:street' v='улица Димитрова' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-521' action='modify' visible='true' lat='53.97455513634307' lon='58.42117149859942'>
|
||||
<tag k='addr:housenumber' v='26' />
|
||||
<tag k='addr:street' v='улица Димитрова' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-519' action='modify' visible='true' lat='53.975606554611346' lon='58.42100253270419'>
|
||||
<tag k='addr:housenumber' v='15' />
|
||||
<tag k='addr:street' v='улица Гафури' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-517' action='modify' visible='true' lat='53.97450959867179' lon='58.417995524551635'>
|
||||
<tag k='addr:housenumber' v='28' />
|
||||
<tag k='addr:street' v='улица Крупской' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-515' action='modify' visible='true' lat='53.973749802634025' lon='58.419208942373444'>
|
||||
<tag k='addr:housenumber' v='38' />
|
||||
<tag k='addr:street' v='улица Крупской' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-513' action='modify' visible='true' lat='53.976781006866105' lon='58.41866226165893'>
|
||||
<tag k='addr:housenumber' v='99' />
|
||||
<tag k='addr:street' v='улица Ленина' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-511' action='modify' visible='true' lat='53.97576508630747' lon='58.416663844469674'>
|
||||
<tag k='addr:housenumber' v='91' />
|
||||
<tag k='addr:street' v='улица Ленина' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-509' action='modify' visible='true' lat='53.97521592138079' lon='58.423429457462575'>
|
||||
<tag k='addr:housenumber' v='114' />
|
||||
<tag k='addr:street' v='улица Карла Маркса' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-507' action='modify' visible='true' lat='53.9758630042496' lon='58.422398578791544'>
|
||||
<tag k='addr:housenumber' v='14' />
|
||||
<tag k='addr:street' v='улица Гафури' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-505' action='modify' visible='true' lat='53.974885907675144' lon='58.42217947696258'>
|
||||
<tag k='addr:housenumber' v='25' />
|
||||
<tag k='addr:street' v='улица Гафури' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-503' action='modify' visible='true' lat='53.977276115619325' lon='58.42432017068545'>
|
||||
<tag k='addr:housenumber' v='3' />
|
||||
<tag k='addr:street' v='Кооперативная улица' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-501' action='modify' visible='true' lat='53.977129433061165' lon='58.42456221218473'>
|
||||
<tag k='addr:housenumber' v='5' />
|
||||
<tag k='addr:street' v='Кооперативная улица' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-499' action='modify' visible='true' lat='53.976987776580465' lon='58.424795959323845'>
|
||||
<tag k='addr:housenumber' v='7' />
|
||||
<tag k='addr:street' v='Кооперативная улица' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-497' action='modify' visible='true' lat='53.97709849365609' lon='58.42161164196259'>
|
||||
<tag k='addr:housenumber' v='1' />
|
||||
<tag k='addr:street' v='улица Дзержинского' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-495' action='modify' visible='true' lat='53.97693767912233' lon='58.4218734580896'>
|
||||
<tag k='addr:housenumber' v='3' />
|
||||
<tag k='addr:street' v='улица Дзержинского' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-493' action='modify' visible='true' lat='53.97679462291104' lon='58.422106361706774'>
|
||||
<tag k='addr:housenumber' v='5' />
|
||||
<tag k='addr:street' v='улица Дзержинского' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-491' action='modify' visible='true' lat='53.97650714155866' lon='58.42257439521804'>
|
||||
<tag k='addr:housenumber' v='9' />
|
||||
<tag k='addr:street' v='улица Дзержинского' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-489' action='modify' visible='true' lat='53.9763666696059' lon='58.42280308915972'>
|
||||
<tag k='addr:housenumber' v='11' />
|
||||
<tag k='addr:street' v='улица Дзержинского' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-487' action='modify' visible='true' lat='53.97622568739016' lon='58.423032613054595'>
|
||||
<tag k='addr:housenumber' v='13' />
|
||||
<tag k='addr:street' v='улица Дзержинского' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-485' action='modify' visible='true' lat='53.975697678444924' lon='58.41775550103164'>
|
||||
<tag k='addr:housenumber' v='1' />
|
||||
<tag k='addr:street' v='улица Димитрова' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-483' action='modify' visible='true' lat='53.97626793931702' lon='58.41828832276258'>
|
||||
<tag k='addr:housenumber' v='2в' />
|
||||
<tag k='addr:street' v='улица Димитрова' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-481' action='modify' visible='true' lat='53.975412116233656' lon='58.41822086937231'>
|
||||
<tag k='addr:housenumber' v='5' />
|
||||
<tag k='addr:street' v='улица Димитрова' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-479' action='modify' visible='true' lat='53.975265581613186' lon='58.418459669244605'>
|
||||
<tag k='addr:housenumber' v='7' />
|
||||
<tag k='addr:street' v='улица Димитрова' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-477' action='modify' visible='true' lat='53.9751001558265' lon='58.4187292540616'>
|
||||
<tag k='addr:housenumber' v='9' />
|
||||
<tag k='addr:street' v='улица Димитрова' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-475' action='modify' visible='true' lat='53.9757041058548' lon='58.419237441519'>
|
||||
<tag k='addr:housenumber' v='10' />
|
||||
<tag k='addr:street' v='улица Димитрова' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-473' action='modify' visible='true' lat='53.974957848348254' lon='58.41896116345482'>
|
||||
<tag k='addr:housenumber' v='11' />
|
||||
<tag k='addr:street' v='улица Димитрова' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-471' action='modify' visible='true' lat='53.97511809771895' lon='58.4187000152511'>
|
||||
<tag k='addr:housenumber' v='12' />
|
||||
<tag k='addr:street' v='улица Димитрова' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-469' action='modify' visible='true' lat='53.97429868877794' lon='58.42172724998295'>
|
||||
<tag k='addr:housenumber' v='28' />
|
||||
<tag k='addr:street' v='улица Димитрова' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-467' action='modify' visible='true' lat='53.97507961223899' lon='58.41708518069071'>
|
||||
<tag k='addr:housenumber' v='18' />
|
||||
<tag k='addr:street' v='улица Крупской' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-465' action='modify' visible='true' lat='53.974944380086036' lon='58.41730115520365'>
|
||||
<tag k='addr:housenumber' v='22' />
|
||||
<tag k='addr:street' v='улица Крупской' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-463' action='modify' visible='true' lat='53.97437280197353' lon='58.41821399475197'>
|
||||
<tag k='addr:housenumber' v='30' />
|
||||
<tag k='addr:street' v='улица Крупской' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-461' action='modify' visible='true' lat='53.97422230088757' lon='58.418454350619164'>
|
||||
<tag k='addr:housenumber' v='32' />
|
||||
<tag k='addr:street' v='улица Крупской' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-459' action='modify' visible='true' lat='53.974059497641925' lon='58.41871435251834'>
|
||||
<tag k='addr:housenumber' v='34' />
|
||||
<tag k='addr:street' v='улица Крупской' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-457' action='modify' visible='true' lat='53.976653591312306' lon='58.41839146725895'>
|
||||
<tag k='addr:housenumber' v='97' />
|
||||
<tag k='addr:street' v='улица Ленина' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-455' action='modify' visible='true' lat='53.976931220250535' lon='58.41895927885895'>
|
||||
<tag k='addr:housenumber' v='101' />
|
||||
<tag k='addr:street' v='улица Ленина' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-453' action='modify' visible='true' lat='53.97690110406299' lon='58.42074257389429'>
|
||||
<tag k='addr:housenumber' v='103' />
|
||||
<tag k='addr:street' v='улица Ленина' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-451' action='modify' visible='true' lat='53.977089739717684' lon='58.4210714587943'>
|
||||
<tag k='addr:housenumber' v='103а' />
|
||||
<tag k='addr:street' v='улица Ленина' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-449' action='modify' visible='true' lat='53.97660243699244' lon='58.419376046645475'>
|
||||
<tag k='addr:housenumber' v='1' />
|
||||
<tag k='addr:street' v='улица Гафури' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-447' action='modify' visible='true' lat='53.97657401651793' lon='58.42126583465086'>
|
||||
<tag k='addr:housenumber' v='4' />
|
||||
<tag k='addr:street' v='улица Гафури' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-445' action='modify' visible='true' lat='53.976316632864204' lon='58.41984282906895'>
|
||||
<tag k='addr:housenumber' v='5' />
|
||||
<tag k='addr:street' v='улица Гафури' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-443' action='modify' visible='true' lat='53.976434258034466' lon='58.42148849141167'>
|
||||
<tag k='addr:housenumber' v='6' />
|
||||
<tag k='addr:street' v='улица Гафури' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-441' action='modify' visible='true' lat='53.97603950793042' lon='58.42029543335817'>
|
||||
<tag k='addr:housenumber' v='9' />
|
||||
<tag k='addr:street' v='улица Гафури' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-439' action='modify' visible='true' lat='53.97589978041945' lon='58.420523637127374'>
|
||||
<tag k='addr:housenumber' v='11' />
|
||||
<tag k='addr:street' v='улица Гафури' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-437' action='modify' visible='true' lat='53.97600773831061' lon='58.42216799831814'>
|
||||
<tag k='addr:housenumber' v='12' />
|
||||
<tag k='addr:street' v='улица Гафури' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-435' action='modify' visible='true' lat='53.97571992354502' lon='58.42262652446251'>
|
||||
<tag k='addr:housenumber' v='16' />
|
||||
<tag k='addr:street' v='улица Гафури' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-433' action='modify' visible='true' lat='53.97546775356539' lon='58.42122922101233'>
|
||||
<tag k='addr:housenumber' v='17' />
|
||||
<tag k='addr:street' v='улица Гафури' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-431' action='modify' visible='true' lat='53.97557754561105' lon='58.4228533497539'>
|
||||
<tag k='addr:housenumber' v='18' />
|
||||
<tag k='addr:street' v='улица Гафури' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-429' action='modify' visible='true' lat='53.975318255367' lon='58.421473378944896'>
|
||||
<tag k='addr:housenumber' v='19' />
|
||||
<tag k='addr:street' v='улица Гафури' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-427' action='modify' visible='true' lat='53.97367412807081' lon='58.4205858082699'>
|
||||
<tag k='addr:housenumber' v='104' />
|
||||
<tag k='addr:street' v='улица Карла Маркса' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-425' action='modify' visible='true' lat='53.97545544516154' lon='58.4239164684713'>
|
||||
<tag k='addr:housenumber' v='116' />
|
||||
<tag k='addr:street' v='улица Карла Маркса' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-423' action='modify' visible='true' lat='53.97555681484945' lon='58.424142802924955'>
|
||||
<tag k='addr:housenumber' v='118' />
|
||||
<tag k='addr:street' v='улица Карла Маркса' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-421' action='modify' visible='true' lat='53.97632016184918' lon='58.425379498565015'>
|
||||
<tag k='addr:housenumber' v='124' />
|
||||
<tag k='addr:street' v='улица Карла Маркса' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-419' action='modify' visible='true' lat='53.976477793319525' lon='58.42563747533085'>
|
||||
<tag k='addr:housenumber' v='13' />
|
||||
<tag k='addr:street' v='Кооперативная улица' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-417' action='modify' visible='true' lat='53.97630807954319' lon='58.42168951251457'>
|
||||
<tag k='addr:housenumber' v='8' />
|
||||
<tag k='addr:street' v='улица Гафури' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
<node id='-415' action='modify' visible='true' lat='53.97467833570392' lon='58.4177260432788'>
|
||||
<tag k='addr:housenumber' v='26' />
|
||||
<tag k='addr:street' v='улица Крупской' />
|
||||
<tag k='source:addr' v='rosreestr.ru' />
|
||||
</node>
|
||||
</osm>
|
||||
@@ -0,0 +1,33 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Leaflet</title>
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css" />
|
||||
<script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"></script>
|
||||
<script src="../layer/vector/TOPOJSON.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div style="width:100%; height:100%" id="map"></div>
|
||||
|
||||
<script type='text/javascript'>
|
||||
var map = L.map('map', {center: L.latLng(58.4, 43.0), zoom: 3});
|
||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);;
|
||||
var borders = new L.TOPOJSON('country.min.topojson', {async: true}).addTo(map);
|
||||
borders.on('addlayer',function (e) {
|
||||
e.layer.eachLayer(function (dist) {
|
||||
var iso = dist.toGeoJSON().properties.ISO2.toLowerCase();
|
||||
dist.bindPopup('<strong>'+dist.toGeoJSON().properties.NAME_ISO+'</strong>',{closeButton:false});
|
||||
if (dist.options) {
|
||||
dist.options.className = 'country country-'+iso;
|
||||
} else {
|
||||
dist.eachLayer(function (dist2) {
|
||||
dist2.options.className = 'country country-'+iso;
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
borders.on('loaded', function (e) { map.fitBounds(e.target.getBounds()); });
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,61 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>L.Yandex controls (addon) example</title>
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css" />
|
||||
<script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"></script>
|
||||
<script src="https://api-maps.yandex.ru/2.1/?lang=en_RU&apikey=<your API-key>" type="text/javascript"></script>
|
||||
<script src="../layer/tile/Yandex.js"></script>
|
||||
<script src="../layer/tile/Yandex.addon.Controls.js"></script>
|
||||
<style>
|
||||
.leaflet-bottom { bottom: 20px }
|
||||
.leaflet-control-attribution { margin-bottom: -10px !important }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div style="width:100%; height:100%" id="map"></div>
|
||||
|
||||
<script>
|
||||
</script>
|
||||
|
||||
<script>
|
||||
var center = [67.6755, 33.936];
|
||||
|
||||
var map = L.map('map', {
|
||||
center: center,
|
||||
zoom: 10
|
||||
});
|
||||
|
||||
map.attributionControl
|
||||
.setPosition('bottomleft')
|
||||
.setPrefix('');
|
||||
|
||||
var baseLayers = {
|
||||
'Yandex map + Traffic': L.yandex('map', {
|
||||
trafficControl: { options: { visible: false }, state: { trafficShown: true } }
|
||||
}),
|
||||
'Yandex + Controls': L.yandex({
|
||||
type: 'map',
|
||||
trafficControl: { options: { size: 'medium' } },
|
||||
typeSelector: true,
|
||||
routeEditor: true
|
||||
}).addTo(map),
|
||||
'OSM': L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||||
})
|
||||
};
|
||||
|
||||
var overlays = {
|
||||
'Overlays': L.yandex({
|
||||
type: 'overlay',
|
||||
routeEditor: true,
|
||||
trafficControl: { state: { trafficShown: true } }
|
||||
})
|
||||
};
|
||||
|
||||
L.control.layers(baseLayers,overlays).addTo(map);
|
||||
map.locate({ setView: true, maxZoom: 14 });
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,44 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>L.Yandex fullscreen (addon) example</title>
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css" />
|
||||
<script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"></script>
|
||||
<script src="https://api-maps.yandex.ru/2.1/?lang=en_RU&apikey=<your API-key>" type="text/javascript"></script>
|
||||
<script src="../layer/tile/Yandex.js"></script>
|
||||
<script src="../layer/tile/Yandex.addon.Fullscreen.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div style="width:80%; height:80%" id="map"></div>
|
||||
|
||||
<p>Rightclick to popup fullscreen view of full-featured Yandex map.</p>
|
||||
<p>Note that no leaflet controls/overlays are visible in that state.</p>
|
||||
|
||||
<script>
|
||||
var center = [67.6755, 33.936];
|
||||
|
||||
var map = L.map('map', {
|
||||
center: center,
|
||||
zoom: 10,
|
||||
attributionControl: false
|
||||
});
|
||||
|
||||
L.yandex({ controlsContainerStyle: false })
|
||||
.on('load',function () {
|
||||
var container = this._yandex.container;
|
||||
container.events.add('contextmenu',function () { // right click or long tap
|
||||
if (!container.isFullscreen()) {
|
||||
container.enterFullscreen();
|
||||
}
|
||||
});
|
||||
})
|
||||
.addTo(map);
|
||||
var marker = L.marker(center, { draggable: true }).addTo(map);
|
||||
map.locate({ setView: true, maxZoom: 14 })
|
||||
.on('locationfound',function (e) {
|
||||
marker.setLatLng(e.latlng);
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,29 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>L.Yandex LoadApi (addon) deferred example</title>
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css" />
|
||||
<script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"></script>
|
||||
<script src="../layer/tile/Yandex.js"></script>
|
||||
<script src="../layer/tile/Yandex.addon.LoadApi.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div style="width:100%; height:100%" id="map"></div>
|
||||
|
||||
<script>
|
||||
var map = L.map('map', {
|
||||
center: [67.6755, 33.936],
|
||||
zoom: 10,
|
||||
attributionControl: false
|
||||
});
|
||||
|
||||
L.control.layers({
|
||||
'(deferred) Yandex': L.yandex({
|
||||
apiParams: '<your API-key>'
|
||||
}),
|
||||
'(deferred) Yandex Hybrid': L.yandex('hybrid')
|
||||
}).addTo(map);
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,29 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>L.Yandex LoadApi (addon) dynamic example</title>
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css" />
|
||||
<script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"></script>
|
||||
<script src="../layer/tile/Yandex.js"></script>
|
||||
<script src="../layer/tile/Yandex.addon.LoadApi.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div style="width:100%; height:100%" id="map"></div>
|
||||
|
||||
<script>
|
||||
var map = L.map('map', {
|
||||
center: [67.6755, 33.936],
|
||||
zoom: 10,
|
||||
attributionControl: false
|
||||
});
|
||||
|
||||
L.control.layers({
|
||||
'Yandex': L.yandex()
|
||||
.loadApi({ apiParams: '<your API-key>' })
|
||||
.addTo(map),
|
||||
'Yandex Hybrid': L.yandex('hybrid')
|
||||
}).addTo(map);
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,31 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>L.Yandex LoadApi (addon) promise example</title>
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css" />
|
||||
<script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"></script>
|
||||
<script src="../layer/tile/Yandex.js"></script>
|
||||
<script src="../layer/tile/Yandex.addon.LoadApi.js"></script>
|
||||
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div style="width:100%; height:100%" id="map"></div>
|
||||
|
||||
<script>
|
||||
var map = L.map('map', {
|
||||
center: [67.6755, 33.936],
|
||||
zoom: 10,
|
||||
attributionControl: false
|
||||
});
|
||||
|
||||
var promise = $.getScript('https://api-maps.yandex.ru/2.1/?lang=en_RU&apikey=<your API-key>');
|
||||
|
||||
L.control.layers({
|
||||
'Yandex': L.yandex({ apiLoader: promise }).addTo(map),
|
||||
'Yandex Hybrid': L.yandex('hybrid')
|
||||
}).addTo(map);
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,54 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>L.Yandex panorama (addon) example</title>
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css" />
|
||||
<script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"></script>
|
||||
<script src="https://api-maps.yandex.ru/2.1/?lang=en_RU&apikey=<your API-key>" type="text/javascript"></script>
|
||||
<script src="../layer/tile/Yandex.js"></script>
|
||||
<script src="../layer/tile/Yandex.addon.Controls.js"></script>
|
||||
<script src="../layer/tile/Yandex.addon.Panorama.js"></script>
|
||||
<style>
|
||||
.leaflet-bottom { bottom: 20px }
|
||||
.leaflet-control-attribution { margin-bottom: -10px !important }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div style="width:80%; height:80%" id="map"></div>
|
||||
|
||||
<p>Special handler used to open panorama player in fullscreen (in order to avoid conflicts with leaflet controls/keyboard).</p>
|
||||
|
||||
<script>
|
||||
var center = [67.6755, 33.936];
|
||||
|
||||
var map = L.map('map', {
|
||||
center: center,
|
||||
zoom: 10
|
||||
});
|
||||
|
||||
map.attributionControl
|
||||
.setPosition('bottomleft')
|
||||
.setPrefix('');
|
||||
|
||||
var baseLayers = {
|
||||
'Yandex + Controls': L.yandex('map', {
|
||||
trafficControl: { options: { size: 'medium' }, state: { trafficShown: false } },
|
||||
typeSelector: true,
|
||||
routeEditor: true,
|
||||
panorama: true
|
||||
}).addTo(map),
|
||||
'OSM': L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||||
})
|
||||
};
|
||||
|
||||
var overlays = {
|
||||
'Panoramas': L.yandex('overlay', { panorama: 'enableLookup' })
|
||||
};
|
||||
|
||||
L.control.layers(baseLayers,overlays).addTo(map);
|
||||
map.locate({ setView: true, maxZoom: 14 });
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,80 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>L.Yandex controls example</title>
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css" />
|
||||
<script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"></script>
|
||||
<script src="https://api-maps.yandex.ru/2.1/?lang=en_RU&apikey=<your API-key>" type="text/javascript"></script>
|
||||
<script src="../layer/tile/Yandex.js"></script>
|
||||
<style>
|
||||
.leaflet-bottom { bottom: 20px }
|
||||
.leaflet-control-attribution { margin-bottom: -10px !important }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div style="width:100%; height:100%" id="map"></div>
|
||||
|
||||
<script>
|
||||
var center = [67.6755, 33.936];
|
||||
|
||||
var map = L.map('map', {
|
||||
center: center,
|
||||
zoom: 10
|
||||
});
|
||||
|
||||
map.attributionControl
|
||||
.setPosition('bottomleft')
|
||||
.setPrefix('');
|
||||
|
||||
L.Yandex.addInitHook('on', 'load', function () {
|
||||
this._setStyle(this._yandex.controls.getContainer(), {
|
||||
left: '45px',
|
||||
right: '57px',
|
||||
top: '3px',
|
||||
width: 'auto'
|
||||
});
|
||||
console.log(this._yandex.controls.getContainer().style.width);
|
||||
});
|
||||
|
||||
var baseLayers = {
|
||||
'Yandex map + Traffic': L.yandex('map')
|
||||
.on('load',function () {
|
||||
this._yandex.controls
|
||||
.add('trafficControl', { visible: false })
|
||||
.get('trafficControl').state.set('trafficShown', true);
|
||||
/* alternative:
|
||||
this._yandex.controls.add(new ymaps.control.TrafficControl({
|
||||
options: { visible: false },
|
||||
state: { trafficShown: true }
|
||||
}));
|
||||
*/
|
||||
}),
|
||||
'Yandex + Controls': L.yandex('map')
|
||||
.on('load',function () {
|
||||
this._yandex.controls
|
||||
.add('trafficControl')
|
||||
.add('typeSelector', { size: 'small', panoramasItemMode: 'off' })
|
||||
.add('routeEditor', { float: 'right' });
|
||||
})
|
||||
.addTo(map),
|
||||
'OSM': L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||||
})
|
||||
};
|
||||
|
||||
var overlays = {
|
||||
'Overlays': L.yandex('overlay')
|
||||
.on('load',function () {
|
||||
this._yandex.controls
|
||||
.add('routeEditor', { float: 'right' })
|
||||
.add('trafficControl', { size: 'small' })
|
||||
.get('trafficControl').state.set('trafficShown', true);
|
||||
})
|
||||
};
|
||||
|
||||
L.control.layers(baseLayers,overlays).addTo(map);
|
||||
map.locate({ setView: true, maxZoom: 14 });
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,118 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>L.Yandex kml/gpx example</title>
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css" />
|
||||
<script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"></script>
|
||||
<script src="https://api-maps.yandex.ru/2.1/?lang=en_RU&apikey=<your API-key>" type="text/javascript"></script>
|
||||
<script src="../layer/tile/Yandex.js"></script>
|
||||
<style>
|
||||
.leaflet-bottom { bottom: 20px }
|
||||
.leaflet-control-attribution { margin-bottom: -10px !important }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div style="width:100%; height:80%" id="map"></div>
|
||||
|
||||
<div id="kml" style="display:none">
|
||||
<p/>
|
||||
<label for="kml-input">KML/GPX url:</label>
|
||||
|
||||
<input type="url" id="kml-input" name="kml"
|
||||
list="defaultURLs">
|
||||
|
||||
<datalist id="defaultURLs">
|
||||
<option value="https://raw.githubusercontent.com/shramov/leaflet-plugins/master/examples/KML_Samples.kml" label="KML_Samples.kml">
|
||||
<option value="https://raw.githubusercontent.com/shramov/leaflet-plugins/master/examples/fells_loop.gpx" label="fells_loop.gpx">
|
||||
</datalist>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var center = [67.6755, 33.936];
|
||||
|
||||
var map = L.map('map', {
|
||||
center: center,
|
||||
zoom: 10
|
||||
});
|
||||
|
||||
map.attributionControl
|
||||
.setPosition('bottomleft')
|
||||
.setPrefix('');
|
||||
|
||||
// https://tech.yandex.ru/maps/jsapi/doc/2.1/dg/concepts/geoxml-docpage/
|
||||
// https://tech.yandex.ru/maps/jsapi/doc/2.1/ref/reference/geoXml.load-docpage/
|
||||
// https://tech.yandex.ru/maps/jsbox/2.1/geoxml_display
|
||||
// https://tech.yandex.ru/maps/jsapi/doc/2.1/dg/concepts/geoobjects-docpage/
|
||||
function loadGeoXml (e) {
|
||||
ymaps.geoXml.load(e.target.value)
|
||||
.done(function (res) {
|
||||
if (!this._map) { return; };
|
||||
onGeoXmlLoad(res,this._yandex);
|
||||
this._resyncView();
|
||||
},this);
|
||||
}
|
||||
|
||||
function onGeoXmlLoad (res,myMap) {
|
||||
applyStyle(res.geoObjects);
|
||||
myMap.geoObjects.add(res.geoObjects);
|
||||
if (res.mapState) {
|
||||
res.mapState.applyToMap(myMap);
|
||||
} else {
|
||||
myMap.setBounds(res.geoObjects.getBounds());
|
||||
}
|
||||
}
|
||||
|
||||
function applyStyle (geoObjects) {
|
||||
geoObjects.each(function (obj) {
|
||||
obj.options.set({preset: 'islands#blackCircleIcon'});
|
||||
if (!obj.geometry) {
|
||||
obj.each(function (obj) {
|
||||
obj.options.set({strokeColor: "9090e8"});
|
||||
obj.options.set({iconImageSize: [16, 0]});
|
||||
});
|
||||
}
|
||||
});
|
||||
return geoObjects;
|
||||
}
|
||||
|
||||
var kmldiv = document.querySelector('div#kml');
|
||||
var kmlinput = kmldiv.querySelector('input#kml-input');
|
||||
var active = 0;
|
||||
|
||||
function onload () {
|
||||
var onChange = loadGeoXml.bind(this);
|
||||
var events = {
|
||||
add: function () {
|
||||
kmlinput.addEventListener('change',onChange);
|
||||
if (!active) { kmldiv.style.display = 'block'; }
|
||||
active++;
|
||||
},
|
||||
remove: function () {
|
||||
kmlinput.removeEventListener('change',onChange);
|
||||
active--;
|
||||
if (!active) { kmldiv.style.display = 'none'; }
|
||||
}
|
||||
};
|
||||
this.on(events);
|
||||
if (this._map) { events.add.call(this); };
|
||||
};
|
||||
|
||||
var baseLayers = {
|
||||
'Yandex map': L.yandex()
|
||||
.on('load',onload)
|
||||
.addTo(map),
|
||||
'OSM': L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||||
})
|
||||
};
|
||||
|
||||
var overlays = {
|
||||
'geoxml': L.yandex('overlay')
|
||||
.on('load',onload)
|
||||
};
|
||||
|
||||
L.control.layers(baseLayers,overlays).addTo(map);
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,62 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>L.Yandex example</title>
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css" />
|
||||
<script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"></script>
|
||||
<script src="https://api-maps.yandex.ru/2.1/?lang=en_RU&apikey=<your API-key>" type="text/javascript"></script>
|
||||
<script src="../layer/tile/Yandex.js"></script>
|
||||
<style>
|
||||
.leaflet-bottom { bottom: 20px }
|
||||
.leaflet-control-attribution { margin-bottom: -10px !important }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div style="width:100%; height:100%" id="map"></div>
|
||||
|
||||
<script>
|
||||
var center = [67.6755, 33.936];
|
||||
|
||||
var map = L.map('map', {
|
||||
center: center,
|
||||
zoom: 10,
|
||||
zoomAnimation: true
|
||||
});
|
||||
|
||||
map.attributionControl
|
||||
.setPosition('bottomleft')
|
||||
.setPrefix('');
|
||||
|
||||
function traffic () {
|
||||
// https://tech.yandex.ru/maps/jsbox/2.1/traffic_provider
|
||||
var actualProvider = new ymaps.traffic.provider.Actual({}, { infoLayerShown: true });
|
||||
actualProvider.setMap(this._yandex);
|
||||
}
|
||||
|
||||
var baseLayers = {
|
||||
'Yandex map': L.yandex() // 'map' is default
|
||||
.addTo(map),
|
||||
'Yandex map + Traffic': L.yandex('map')
|
||||
.on('load', traffic),
|
||||
'Yandex satellite': L.yandex({ type: 'satellite' }), // type can be set in options
|
||||
'Yandex hybrid': L.yandex('hybrid'),
|
||||
'OSM': L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||||
})
|
||||
};
|
||||
|
||||
var overlays = {
|
||||
'Traffic': L.yandex('overlay')
|
||||
.on('load', traffic)
|
||||
};
|
||||
|
||||
L.control.layers(baseLayers,overlays).addTo(map);
|
||||
var marker = L.marker(center, { draggable: true }).addTo(map);
|
||||
map.locate({ setView: true, maxZoom: 14 })
|
||||
.on('locationfound',function (e) {
|
||||
marker.setLatLng(e.latlng);
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||