Editing polygons in leaflet.js and leaflet.snap - javascript

I'm using leaflet.snap (http://makinacorpus.github.io/Leaflet.Snap/) which lets me snap points to lines when drawing a polygon - just what I need. BUT I'm having a hard time trying to get set the polygons to be editable.
Here's my code, which uses Leaflet.Snap, and allows drawing but not editing of a polygon. Any help getting the polygons editable is much appreciated.
<!DOCTYPE html>
<html>
<head>
<title>Leaflet Snap Test</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Leaflet -->
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css" />
<script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
<style>
.leaflet-editing-icon.marker-snapped {
background-color: yellow;
}
</style>
<link rel="stylesheet" href="http://makinacorpus.github.io/Leaflet.Snap/Leaflet.draw/dist/leaflet.draw.css" />
<script src="http://makinacorpus.github.io/Leaflet.Snap/Leaflet.draw/dist/leaflet.draw.js"></script>
<script src="http://makinacorpus.github.io/Leaflet.Snap/Leaflet.GeometryUtil/dist/leaflet.geometryutil.js"></script>
<script src="http://makinacorpus.github.io/Leaflet.Snap/leaflet.snap.js"></script>
</head>
<body>
<div id="map" class="map" style="height: 500px; width: 800px"></div>
<script>
var theTileLayer = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: 'Map data © 2013 OpenStreetMap contributors',
});
var map = L.map('map').setView([45.4835656, -122.7332588], 12).addLayer(theTileLayer);
var guideLayers = new Array();
var drawnItems = new L.FeatureGroup();
map.addLayer(drawnItems);
var drawControl = new L.Control.Draw({
position: 'topright',
draw: {
polyline: false,
polygon: {
shapeOptions: {
color: '#009900'
}
},
circle: false, // Turns off this drawing tool
rectangle: false,
marker: false
},
edit: {
featureGroup: drawnItems, //REQUIRED!!
remove: true
}
});
map.addControl(drawControl);
// Editing lines works fine on the sample (http://makinacorpus.github.io/Leaflet.Snap/) but not below.
drawControl.setDrawingOptions({
polygon: { guideLayers: guideLayers, snapDistance: 15 },
});
map.on('draw:created', function (e) {
var layer = e.layer;
map.addLayer(layer);
guideLayers.push(layer);
});
</script>
</body>
</html>

It's just you missed to add layer to drawnItems while any drawing is complete. Just replace "map" by "drawnItems" in your code like following and it will work:
map.on('draw:created', function (e) {
var layer = e.layer;
drawnItems.addLayer(layer);
guideLayers.push(layer);
});
Enjoy!

Related

How to detect in JavaScript if request made in getTileUrl (Google Maps) was successful or not?

I am new to the community,
I have a simple google Map overlay, I get the tiles (format png) from an external service, example: https://example.tiles.com/
I need to monitor or some mechanism in JavaScript to track or detect successful, failed requests made by getTileUrl to the external service, I have searched the official documentation and found nothing.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Map</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<style>
#map {
width: 600px;
height: 500px;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
let gmap;
function initMap() {
gmap = new google.maps.Map(document.getElementById('map'), {
center: {lat: 44.9648, lng: -93.252},
zoom: 5
});
const layers = new google.maps.ImageMapType({
getTileUrl: function(coord, zoom) {
return ['https://example.tiles.com/', zoom, '/', coord.x, '/', coord.y, '/current.png'].join('');
},
tileSize: new google.maps.Size(256, 256)
});
gmap.overlayMapTypes.push(layers);
};
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=GOOGLE_API_KEY&callback=initMap" async defer></script>
</body>
</html>
I have tried with the tilesloaded listener but it does not support function arguments.
google.maps.event.addListenerOnce(gmap, 'tilesloaded', function(){
..
});
tilesloaded
What is wanted is simply to count the successful requests made to https://example.tiles.com/ by getTileUrl
I tried using the 'tilesloaded' and it worked for me using this:
google.maps.event.addListenerOnce(gmap, 'tilesloaded', function(){
alert("Tile is loaded!")
});
I just changed the first parameter map into gmap because that's how you defined the map instance on your code.
Here's a snippet for you to check if this is how you want it to happen:
let gmap;
function initMap() {
gmap = new google.maps.Map(document.getElementById('map'), {
center: {lat: 44.9648, lng: -93.252},
zoom: 5
});
const layers = new google.maps.ImageMapType({
getTileUrl: function(coord, zoom) {
return ['https://example.tiles.com/', zoom, '/', coord.x, '/', coord.y, '/current.png'].join('');
},
tileSize: new google.maps.Size(256, 256)
});
gmap.overlayMapTypes.push(layers);
google.maps.event.addListenerOnce(gmap, 'tilesloaded', function(){
alert("Tile is loaded!")
});
};
#map {
width: 600px;
height: 500px;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Map</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
</head>
<body>
<div id="map"></div>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap" async defer></script>
</body>
</html>
What happens here is when the tilesloaded is triggered, it will send an alert with text "Tile is Loaded!".
Hope this helps.

How to pause a leaflet panTo() animation

I am trying to make a map that automatically pan to several locations, one after the other, using Leaflet 1.7.1. This is working quite well using the panTo() function :
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.7.1/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet#1.7.1/dist/leaflet.js"></script>
<style>
html,body,#map {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id='map'></div>
</body>
<script type='text/javascript' src='script.js'></script>
</html>
script.js
var map = L.map('map');
var osm = new L.TileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: 'OpenStreetMap contributors'
}).addTo(map);
map.dragging.disable();
map.setView([48.980, 4.373], 7);
var athens = [37.9844, 23.7398]
var stockholm = [59.3272, 18.0830]
setTimeout(function() {
map.panTo([athens[0], athens[1]], {
animate: true,
duration: 20,
easeLinearity: 0.9
})
}, 2000);
setTimeout(function() {
map.panTo([stockholm[0], stockholm[1]], {
animate: true,
duration: 15,
easeLinearity: 0.9
})
}, 22000);
I would like to add a pause/resume function, but I cannot figure how to do this. I am able to stop the animation using the following command :
map.setView(map.getCenter(), map.getZoom(), {"animate": false});
But I cannot resume the animation afterwards, and the later timed panTo events will happen anyway.
Any leads or ideas on how to achieve that ?

How to get layer ID from existing google map

I'm trying to toggle layers of an existing map created on maps.google.com with google V3 API.
To toggle (display / hide) the layer I'm using .setMap function with map/null as argument.
My problem is that I've not found a way to get the list of the existing layers. So I've hardcoded the values in mapLayerNames, but I would have prefer to get them from 'map' variable. Which API am I missing from the doc?
here comes my code: lid are the layer Ids I'm looking for in the url...
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<title>KML Layers</title>
<style>
html, body, #map-canvas {
height: 100%;
margin: 0px;
padding: 0px
}
</style>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true"></script>
<script>
var mapLayerNames = [
"http://www.google.com/maps/d/u/1/kml?mid=z_wfVyI764I4.kPvsE6js2GAg&lid=z_wfVyI764I4.kIQKW-gOFhmU",
"http://www.google.com/maps/d/u/1/kml?mid=z_wfVyI764I4.kPvsE6js2GAg&lid=z_wfVyI764I4.k2u4vYNOkUIA",
"http://www.google.com/maps/d/u/1/kml?mid=z_wfVyI764I4.kPvsE6js2GAg&lid=z_wfVyI764I4.kcPBYmgvyhbI"
];
var map;
var ctaLayer = [];
function initialize() {
var paris = new google.maps.LatLng(43.5742118,1.4538968);
var mapOptions = {
zoom: 11,
center: paris
}
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
for (var i=0; i<mapLayerNames.length; i++) {
ctaLayer = new google.maps.KmlLayer({
url: mapLayerNames[i]
});
ctaLayer.setMap(map);
}
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map-canvas"></div>
</body>
</html>

Manually setting basemap using ArcGIS API for JavaScript?

Looked over the example can NOT figure out how to set basemap MANUALLY. I don't want a dijit widget, or any other libraries or anything like that. Just want to manually set a basemap to any of the already available types like Topographic, Satellites, Streets, etc.
Following this API reference:
Object: esri/basemaps
The part I can't figure out is marked with question marks. If some could help me out, would really appreciate it.
require([
"esri/basemaps",
"esri/map",
"dojo/domReady!"
], function (esriBasemaps, Map) {
/* ------------------------------------- */
/* Basemap add one of the existing maps. */
/* ------------------------------------- */
esriBasemaps.myBasemap = {
baseMapLayers ???
};
var map = new Map("map", {
basemap: "myBasemap",
center: [-118, 34.5],
zoom: 8
});
});
The code in the esri/basemaps documentation works fine, combined with the create a map sample.
Here's the part you wondered about:
esriBasemaps.myBasemap = {
baseMapLayers: [
{
url: "http://services.arcgisonline.com/ArcGIS/rest/services/Specialty/DeLorme_World_Base_Map/MapServer"
}
],
title: "My Basemap"
};
Here's a full example. Copy and paste the following into the ArcGIS API for JavaScript Sandbox to see how it works.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
<title>Simple Map</title>
<link rel="stylesheet" href="http://js.arcgis.com/3.13/esri/css/esri.css">
<style>
html, body, #map {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
body {
background-color: #FFF;
overflow: hidden;
font-family: "Trebuchet MS";
}
</style>
<script src="http://js.arcgis.com/3.13/"></script>
<script>
var map;
require(["esri/basemaps", "esri/map", "dojo/domReady!"], function(esriBasemaps, Map) {
esriBasemaps.myBasemap = {
baseMapLayers: [
{
url: "http://services.arcgisonline.com/ArcGIS/rest/services/Specialty/DeLorme_World_Base_Map/MapServer"
}
],
title: "My Basemap"
};
map = new Map("map", {
basemap: "myBasemap",
center: [-122.45, 37.75], // longitude, latitude
zoom: 13
});
});
</script>
</head>
<body>
<div id="map"></div>
</body>
</html>

JavaScript Parsing Outside XML/KML - Geoxml3

I have implemented a script that parses KML into a Google map, as described here. There's also a working sample here.
This works great in Safari and IE, but nothing happens in Firefox or Chrome on my installation (still local) and on the demo site. The only thing in the log is this:
--[13:07:38.076] "Unable to retrieve station.kml"
Could someone take a look at this and shed some light? I'm not proficient enough in JavaScript to figure out what's going on.
Thanks!
UPDATE: Here's my actual code.
<!DOCTYPE html>
<html class="no-js" lang="en"> <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Where Are Our Alumni?</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<style type="text/css">
body, html {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
div#map-canvas {
width: 100%; height: 100%;
}
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="geoxml3.js"></script>
<script src="markerclusterer.js"></script>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" charset="utf-8">
$(document).ready(function(){
var myOptions = {
center: new google.maps.LatLng(41.8813571,-87.6294174),
zoom: 3,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var mcOptions = {gridSize: 50, maxZoom: 15};
var weather_url = "http://api.wunderground.com/api/6d9cb153ba3be6c0/conditions/forecast/q/";
var count = 0;
markers = [];
var map = new google.maps.Map(document.getElementById("map-canvas"), myOptions);
markerclusterer = new MarkerClusterer(map, [], mcOptions);
var infoWindow = new google.maps.InfoWindow({maxWidth:800});
var myParser = new geoXML3.parser({
map: map, singleInfoWindow:true,
createMarker:function(placemark){
if (placemark.point.lat != '0') {
var point = new google.maps.LatLng(placemark.point.lat, placemark.point.lng);
var marker = new google.maps.Marker({position:point});
markers.push(marker);
google.maps.event.addListener(marker, "click", function(){
var marker_lat = marker.getPosition().lat();
var marker_lng = marker.getPosition().lng();
var request_url = weather_url + (marker_lat + "," + marker_lng);
infoWindow.close();
infoWindow.setOptions({maxWidth:800});
content = ("<div><strong>" + placemark.name + "</strong><br>");
content += (placemark.description + "</div>");
infoWindow.setContent(content);
infoWindow.open(map, marker);
});
markerclusterer.addMarker(marker);
}
}
});
myParser.parse('alumni.kml');
});
function clickMarker(i){
google.maps.event.trigger(markers[i], "click");
}
</script>
</head>
<body>
<div id="map-canvas"></div>
</body>
</html>
The geoxml3.js script is what's causing the error, available from here.
Looks like you are using an old version of geoxml3. You should use the latest version from the polys branch, unless you need KMZ support, in which case, use the latest version from the kmz branch.
Working example of clustered markers from KML with geoxml3

Categories