I am using javascript library leaflet to deal with map, I did the location searching part now I want that user can draw circle, line and polygon on the map but the could is not working. The toolbar of searching is visible but of the shapes is not. Can any one point out eh mistake in my code, Thanks in advance.
Here is my code:
<!DOCTYPE html>
<html>
<head>
<!-- Load Leaflet from CDN-->
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet/dist/leaflet-src.js"></script>
<!-- Load Esri Leaflet from CDN -->
<script src="https://unpkg.com/esri-leaflet"></script>
<!-- Esri Leaflet Geocoder -->
<link rel="stylesheet" href="https://unpkg.com/esri-leaflet-geocoder/dist/esri-leaflet-geocoder.css">
<script src="https://unpkg.com/esri-leaflet-geocoder"></script>
<script src="node_modules/leaflet-toolbar/dist/leaflet.toolbar.js"></script>
<link rel="stylesheet" href="node_modules/leaflet-toolbar/dist/leaflet.toolbar.css" />
<link rel="stylesheet" href="node_modules/leaflet-draw-toolbar/dist/leaflet.draw-toolbar.css" />
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<!---- <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script src="../node_modules/leaflet/dist/leaflet-src.js"></script>
<script src="../node_modules/leaflet-toolbar/dist/leaflet.toolbar-src.js"></script>
<script src="../node_modules/leaflet-draw/dist/leaflet.draw-src.js"></script>--!-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.2/leaflet.draw.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.2/leaflet.draw.js"></script>
<script src="https://cdn.jsdelivr.net/npm/#turf/turf#5/turf.min.js"></script>
<style>
#map {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
</style>
</head>
<body>
<div id="map"> </div>
<script>
var center = [-33.8650, 151.2094];
var map = L.map('map').setView([0, 0], 6);
drawnItems = new L.FeatureGroup().addTo(map);
L.tileLayer('https://api.maptiler.com/maps/streets/{z}/{x}/{y}.png?key=eL1sdTPWF7XeyxpLvpGq', {
attribution: '© MapTiler © OpenStreetMap contributors'
}).addTo(map);
var searchContrl = L.esri.Geocoding.geosearch().addTo(map);
//adding layergroup to search control
var results = L.layerGroup.addTo(map);
searchContrl.on('results', function(data) {
results.clearLayers();
for (var i = data.results.length - 1; i >= 0; i--) {
results.addLayer(L.marker(data.results[i].latlong));
}
});
var editableLayers = new L.FeatureGroup();
map.addLayer(editableLayers);
var MyCustomMarker = L.Icon.extend({
options: {
shadowUrl: null,
iconAnchor: new L.Point(12, 12),
iconSize: new L.Point(24, 24),
iconUrl: 'link/to/image.png'
}
});
var options = {
position: 'topright',
draw: {
polyline: {
shapeOptions: {
color: '#f357a1',
weight: 10
}
},
polygon: {
allowIntersection: false, // Restricts shapes to simple polygons
drawError: {
color: '#e1e100', // Color the shape will turn when intersects
message: '<strong>Oh snap!<strong> you can\'t draw that!' // Message that will show when intersect
},
shapeOptions: {
color: '#bada55'
}
},
circle: false, // Turns off this drawing tool
rectangle: {
shapeOptions: {
clickable: false
}
},
marker: {
icon: new MyCustomMarker()
}
},
edit: {
featureGroup: editableLayers, //REQUIRED!!
remove: false
}
};
var drawControl = new L.Control.Draw(options);
map.addControl(drawControl);
map.on(L.Draw.Event.CREATED, function(e) {
var type = e.layerType,
layer = e.layer;
if (type === 'marker') {
layer.bindPopup('A popup!');
}
editableLayers.addLayer(layer);
});
</script>
</body>
</html>
The use is wrong
var results = L.layerGroup.addTo(map);
should be
var results = new L.LayerGroup().addTo(map);
(Like you did in the search container)
<!DOCTYPE html>
<html>
<head>
<!-- Load Leaflet from CDN-->
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet/dist/leaflet-src.js"></script>
<!-- Load Esri Leaflet from CDN -->
<script src="https://unpkg.com/esri-leaflet"></script>
<!-- Esri Leaflet Geocoder -->
<link rel="stylesheet" href="https://unpkg.com/esri-leaflet-geocoder/dist/esri-leaflet-geocoder.css">
<script src="https://unpkg.com/esri-leaflet-geocoder"></script>
<script src="node_modules/leaflet-toolbar/dist/leaflet.toolbar.js"></script>
<link rel="stylesheet" href="node_modules/leaflet-toolbar/dist/leaflet.toolbar.css" />
<link rel="stylesheet" href="node_modules/leaflet-draw-toolbar/dist/leaflet.draw-toolbar.css" />
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<!---- <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script src="../node_modules/leaflet/dist/leaflet-src.js"></script>
<script src="../node_modules/leaflet-toolbar/dist/leaflet.toolbar-src.js"></script>
<script src="../node_modules/leaflet-draw/dist/leaflet.draw-src.js"></script>--!-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.2/leaflet.draw.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.2/leaflet.draw.js"></script>
<script src="https://cdn.jsdelivr.net/npm/#turf/turf#5/turf.min.js"></script>
<style>
#map {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
</style>
</head>
<body>
<div id="map"> </div>
<script>
var center = [-33.8650, 151.2094];
var map = L.map('map').setView([0, 0], 6);
drawnItems = new L.FeatureGroup().addTo(map);
L.tileLayer('https://api.maptiler.com/maps/streets/{z}/{x}/{y}.png?key=eL1sdTPWF7XeyxpLvpGq', {
attribution: '© MapTiler © OpenStreetMap contributors'
}).addTo(map);
var searchContrl = L.esri.Geocoding.geosearch().addTo(map);
//adding layergroup to search control
console.log(L.LayerGroup);
var results = new L.LayerGroup().addTo(map);
searchContrl.on('results', function(data) {
results.clearLayers();
for (var i = data.results.length - 1; i >= 0; i--) {
results.addLayer(L.marker(data.results[i].latlong));
}
});
var editableLayers = new L.FeatureGroup();
map.addLayer(editableLayers);
var MyCustomMarker = L.Icon.extend({
options: {
shadowUrl: null,
iconAnchor: new L.Point(12, 12),
iconSize: new L.Point(24, 24),
iconUrl: 'link/to/image.png'
}
});
var options = {
position: 'topright',
draw: {
polyline: {
shapeOptions: {
color: '#f357a1',
weight: 10
}
},
polygon: {
allowIntersection: false, // Restricts shapes to simple polygons
drawError: {
color: '#e1e100', // Color the shape will turn when intersects
message: '<strong>Oh snap!<strong> you can\'t draw that!' // Message that will show when intersect
},
shapeOptions: {
color: '#bada55'
}
},
circle: false, // Turns off this drawing tool
rectangle: {
shapeOptions: {
clickable: false
}
},
marker: {
icon: new MyCustomMarker()
}
},
edit: {
featureGroup: editableLayers, //REQUIRED!!
remove: false
}
};
var drawControl = new L.Control.Draw(options);
map.addControl(drawControl);
map.on(L.Draw.Event.CREATED, function(e) {
var type = e.layerType,
layer = e.layer;
if (type === 'marker') {
layer.bindPopup('A popup!');
}
editableLayers.addLayer(layer);
});
</script>
</body>
</html>
BTW, I used var because of your syntax but const and let are much better.
I am trying swich map box to google maps in some map app.
This shows polyline on map, but i have one problem.
Here is my code :
<!DOCTYPE html>
<html>
<head>
<title>Simple Map</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<style>
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html, body {
height: 100%;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div id="map"></div>
<script src="https://portal.company.io/theme/plugins/moment.js"></script>
<script src="https://portal.company.io/Scripts/googlemap/mapstyle.js"></script>
<script src="https://portal.company.io/Scripts/googlemap/markerclusterer.js"></script>
<script type="text/javascript">
(function(t,e){"function"==typeof define&&define.amd?define(["leaflet"],t):"object"==typeof exports&&(module.exports=t(require("leaflet"))),e!==void 0&&e.L&&(e.LeafletLabel=t(L))})(function(t){t.labelVersion="0.2.4";var e=t.Class.extend({includes:t.Mixin.Events,options:{className:"",clickable:!1,direction:"right",noHide:!1,offset:[12,-15],opacity:1,zoomAnimation:!0},initialize:function(e,i){t.setOptions(this,e),this._source=i,this._animated=t.Browser.any3d&&this.options.zoomAnimation,this._isOpen=!1},onAdd:function(e){this._map=e,this._pane=this.options.pane?e._panes[this.options.pane]:this._source instanceof t.Marker?e._panes.markerPane:e._panes.popupPane,this._container||this._initLayout(),this._pane.appendChild(this._container),this._initInteraction(),this._update(),this.setOpacity(this.options.opacity),e.on("moveend",this._onMoveEnd,this).on("viewreset",this._onViewReset,this),this._animated&&e.on("zoomanim",this._zoomAnimation,this),t.Browser.touch&&!this.options.noHide&&(t.DomEvent.on(this._container,"click",this.close,this),e.on("click",this.close,this))},onRemove:function(t){this._pane.removeChild(this._container),t.off({zoomanim:this._zoomAnimation,moveend:this._onMoveEnd,viewreset:this._onViewReset},this),this._removeInteraction(),this._map=null},setLatLng:function(e){return this._latlng=t.latLng(e),this._map&&this._updatePosition(),this},setContent:function(t){return this._previousContent=this._content,this._content=t,this._updateContent(),this},close:function(){var e=this._map;e&&(t.Browser.touch&&!this.options.noHide&&(t.DomEvent.off(this._container,"click",this.close),e.off("click",this.close,this)),e.removeLayer(this))},updateZIndex:function(t){this._zIndex=t,this._container&&this._zIndex&&(this._container.style.zIndex=t)},setOpacity:function(e){this.options.opacity=e,this._container&&t.DomUtil.setOpacity(this._container,e)},_initLayout:function(){this._container=t.DomUtil.create("div","leaflet-label "+this.options.className+" leaflet-zoom-animated"),this.updateZIndex(this._zIndex)},_update:function(){this._map&&(this._container.style.visibility="hidden",this._updateContent(),this._updatePosition(),this._container.style.visibility="")},_updateContent:function(){this._content&&this._map&&this._prevContent!==this._content&&"string"==typeof this._content&&(this._container.innerHTML=this._content,this._prevContent=this._content,this._labelWidth=this._container.offsetWidth)},_updatePosition:function(){var t=this._map.latLngToLayerPoint(this._latlng);this._setPosition(t)},_setPosition:function(e){var i=this._map,n=this._container,o=i.latLngToContainerPoint(i.getCenter()),s=i.layerPointToContainerPoint(e),a=this.options.direction,l=this._labelWidth,h=t.point(this.options.offset);"right"===a||"auto"===a&&s.x<o.x?(t.DomUtil.addClass(n,"leaflet-label-right"),t.DomUtil.removeClass(n,"leaflet-label-left"),e=e.add(h)):(t.DomUtil.addClass(n,"leaflet-label-left"),t.DomUtil.removeClass(n,"leaflet-label-right"),e=e.add(t.point(-h.x-l,h.y))),t.DomUtil.setPosition(n,e)},_zoomAnimation:function(t){var e=this._map._latLngToNewLayerPoint(this._latlng,t.zoom,t.center).round();this._setPosition(e)},_onMoveEnd:function(){this._animated&&"auto"!==this.options.direction||this._updatePosition()},_onViewReset:function(t){t&&t.hard&&this._update()},_initInteraction:function(){if(this.options.clickable){var e=this._container,i=["dblclick","mousedown","mouseover","mouseout","contextmenu"];t.DomUtil.addClass(e,"leaflet-clickable"),t.DomEvent.on(e,"click",this._onMouseClick,this);for(var n=0;i.length>n;n++)t.DomEvent.on(e,i[n],this._fireMouseEvent,this)}},_removeInteraction:function(){if(this.options.clickable){var e=this._container,i=["dblclick","mousedown","mouseover","mouseout","contextmenu"];t.DomUtil.removeClass(e,"leaflet-clickable"),t.DomEvent.off(e,"click",this._onMouseClick,this);for(var n=0;i.length>n;n++)t.DomEvent.off(e,i[n],this._fireMouseEvent,this)}},_onMouseClick:function(e){this.hasEventListeners(e.type)&&t.DomEvent.stopPropagation(e),this.fire(e.type,{originalEvent:e})},_fireMouseEvent:function(e){this.fire(e.type,{originalEvent:e}),"contextmenu"===e.type&&this.hasEventListeners(e.type)&&t.DomEvent.preventDefault(e),"mousedown"!==e.type?t.DomEvent.stopPropagation(e):t.DomEvent.preventDefault(e)}});return t.BaseMarkerMethods={showLabel:function(){return this.label&&this._map&&(this.label.setLatLng(this._latlng),this._map.showLabel(this.label)),this},hideLabel:function(){return this.label&&this.label.close(),this},setLabelNoHide:function(t){this._labelNoHide!==t&&(this._labelNoHide=t,t?(this._removeLabelRevealHandlers(),this.showLabel()):(this._addLabelRevealHandlers(),this.hideLabel()))},bindLabel:function(i,n){var o=this.options.icon?this.options.icon.options.labelAnchor:this.options.labelAnchor,s=t.point(o)||t.point(0,0);return s=s.add(e.prototype.options.offset),n&&n.offset&&(s=s.add(n.offset)),n=t.Util.extend({offset:s},n),this._labelNoHide=n.noHide,this.label||(this._labelNoHide||this._addLabelRevealHandlers(),this.on("remove",this.hideLabel,this).on("move",this._moveLabel,this).on("add",this._onMarkerAdd,this),this._hasLabelHandlers=!0),this.label=new e(n,this).setContent(i),this},unbindLabel:function(){return this.label&&(this.hideLabel(),this.label=null,this._hasLabelHandlers&&(this._labelNoHide||this._removeLabelRevealHandlers(),this.off("remove",this.hideLabel,this).off("move",this._moveLabel,this).off("add",this._onMarkerAdd,this)),this._hasLabelHandlers=!1),this},updateLabelContent:function(t){this.label&&this.label.setContent(t)},getLabel:function(){return this.label},_onMarkerAdd:function(){this._labelNoHide&&this.showLabel()},_addLabelRevealHandlers:function(){this.on("mouseover",this.showLabel,this).on("mouseout",this.hideLabel,this),t.Browser.touch&&this.on("click",this.showLabel,this)},_removeLabelRevealHandlers:function(){this.off("mouseover",this.showLabel,this).off("mouseout",this.hideLabel,this),t.Browser.touch&&this.off("click",this.showLabel,this)},_moveLabel:function(t){this.label.setLatLng(t.latlng)}},t.Icon.Default.mergeOptions({labelAnchor:new t.Point(9,-20)}),t.Marker.mergeOptions({icon:new t.Icon.Default}),t.Marker.include(t.BaseMarkerMethods),t.Marker.include({_originalUpdateZIndex:t.Marker.prototype._updateZIndex,_updateZIndex:function(t){var e=this._zIndex+t;this._originalUpdateZIndex(t),this.label&&this.label.updateZIndex(e)},_originalSetOpacity:t.Marker.prototype.setOpacity,setOpacity:function(t,e){this.options.labelHasSemiTransparency=e,this._originalSetOpacity(t)},_originalUpdateOpacity:t.Marker.prototype._updateOpacity,_updateOpacity:function(){var t=0===this.options.opacity?0:1;this._originalUpdateOpacity(),this.label&&this.label.setOpacity(this.options.labelHasSemiTransparency?this.options.opacity:t)},_originalSetLatLng:t.Marker.prototype.setLatLng,setLatLng:function(t){return this.label&&!this._labelNoHide&&this.hideLabel(),this._originalSetLatLng(t)}}),t.CircleMarker.mergeOptions({labelAnchor:new t.Point(0,0)}),t.CircleMarker.include(t.BaseMarkerMethods),t.Path.include({bindLabel:function(i,n){return this.label&&this.label.options===n||(this.label=new e(n,this)),this.label.setContent(i),this._showLabelAdded||(this.on("mouseover",this._showLabel,this).on("mousemove",this._moveLabel,this).on("mouseout remove",this._hideLabel,this),t.Browser.touch&&this.on("click",this._showLabel,this),this._showLabelAdded=!0),this},unbindLabel:function(){return this.label&&(this._hideLabel(),this.label=null,this._showLabelAdded=!1,this.off("mouseover",this._showLabel,this).off("mousemove",this._moveLabel,this).off("mouseout remove",this._hideLabel,this)),this},updateLabelContent:function(t){this.label&&this.label.setContent(t)},_showLabel:function(t){this.label.setLatLng(t.latlng),this._map.showLabel(this.label)},_moveLabel:function(t){this.label.setLatLng(t.latlng)},_hideLabel:function(){this.label.close()}}),t.Map.include({showLabel:function(t){return this.addLayer(t)}}),t.FeatureGroup.include({clearLayers:function(){return this.unbindLabel(),this.eachLayer(this.removeLayer,this),this},bindLabel:function(t,e){return this.invoke("bindLabel",t,e)},unbindLabel:function(){return this.invoke("unbindLabel")},updateLabelContent:function(t){this.invoke("updateLabelContent",t)}}),e},window);
</script>
<script>
var itm = [{"TrackingAvgSpeed":-1.0,"OverspeedPercent":0,"AvgAllowedSpeed":50.0,"DistanceInMeters":43,"Points":0.0,"Polyline":"qobxHcdujCADC???ICKK??COEMGI??EEGAE?","CalculatedAvgSpeed":21.6},{"TrackingAvgSpeed":-1.0,"OverspeedPercent":0,"AvgAllowedSpeed":50.0,"DistanceInMeters":35,"Points":0.0,"Polyline":"sqbxH}eujCG???GDGFEJ??CJAJ?J#J","CalculatedAvgSpeed":21.6},{"TrackingAvgSpeed":-1.0,"OverspeedPercent":0,"AvgAllowedSpeed":50.0,"DistanceInMeters":257,"Points":0.0,"Polyline":"urbxHscujC#LDHDH??#L?^??A`#GlBKdCKzCIvAInAI|#","CalculatedAvgSpeed":31.68},{"TrackingAvgSpeed":-1.0,"OverspeedPercent":100,"AvgAllowedSpeed":50.0,"DistanceInMeters":300,"Points":0.0,"Polyline":"etbxHkltjCGt#Kx#Ix#O~#Kp#Kr#Qv#]hBaAfF??M\\??G#GBGDEH","CalculatedAvgSpeed":65.73333},{"TrackingAvgSpeed":-1.0,"OverspeedPercent":0,"AvgAllowedSpeed":50.0,"DistanceInMeters":42,"Points":0.0,"Polyline":"i{bxH}ssjCCHCHAJ???NBN??BL??Cj#","CalculatedAvgSpeed":29.4},{"TrackingAvgSpeed":-1.0,"OverspeedPercent":0,"AvgAllowedSpeed":50.0,"DistanceInMeters":105,"Points":0.0,"Polyline":"o{bxHcpsjCqApG","CalculatedAvgSpeed":43.2},{"TrackingAvgSpeed":-1.0,"OverspeedPercent":100,"AvgAllowedSpeed":50.0,"DistanceInMeters":656,"Points":0.0,"Polyline":"a~bxHqgsjCUpA??Ot#Sv#Uz#Wv#??KZ??IV??i#bBW~#Ol#Mp#??G\\Gr#Ej#Cv#?r#??GdCCp#El#Gh#Eh#??Kl#Id#Kf#??Kb#Mb#K^MZO^Q^Wd#??S\\UXWXUT]\\","CalculatedAvgSpeed":68.21053},{"TrackingAvgSpeed":-1.0,"OverspeedPercent":100,"AvgAllowedSpeed":70.0,"DistanceInMeters":716,"Points":0.0,"Polyline":"_ocxHusqjCi#b#cG|EsHbGs#l#a#`#YZSXU\\U^Sb#Sd#Q`#M`#Md#Oh#Kf#??ET??Od#Ox#QdAGl#C\\AZ","CalculatedAvgSpeed":79.8},{"TrackingAvgSpeed":-1.0,"OverspeedPercent":100,"AvgAllowedSpeed":70.0,"DistanceInMeters":21,"Points":0.0,"Polyline":"imdxHalpjCAT?h#","CalculatedAvgSpeed":72.0},{"TrackingAvgSpeed":-1.0,"OverspeedPercent":62,"AvgAllowedSpeed":92.16,"DistanceInMeters":2465,"Points":0.0,"Polyline":"kmdxHajpjC?`A??#nAHrCTpH??HtG??f#db#^rZ??FbGNvL#x#Dx#Br#Dn#??Dn#JbAJfATjBrBnQ??`Flc#??bBxN??RfB??`BjN","CalculatedAvgSpeed":93.24},{"TrackingAvgSpeed":-1.0,"OverspeedPercent":100,"AvgAllowedSpeed":72.76,"DistanceInMeters":2533,"Points":0.0,"Polyline":"iucxHqpijC#F??vCbWfBbORdBZ`C??xAlK\\rCVzBn#jG~ArO??h#fF??h#dFfAjJ??tApL??`Ex]??h#vE??jBjP??D^??|#rH??vB`R","CalculatedAvgSpeed":100.28},{"TrackingAvgSpeed":-1.0,"OverspeedPercent":100,"AvgAllowedSpeed":90.0,"DistanceInMeters":1133,"Points":0.0,"Polyline":"qjbxH{vbjC\\xC??RfB??p#|F??fAnJ??X|B??b#vD??l#dF??f#lE??pArKVxB??H|#Jv#Bd#B^Bb#FdBDtA??FbCBr#???Z?\\A`#Af#Er#K|A??UrC","CalculatedAvgSpeed":98.42553},{"TrackingAvgSpeed":-1.0,"OverspeedPercent":0,"AvgAllowedSpeed":93.94,"DistanceInMeters":1036,"Points":0.0,"Polyline":"w|axHus_jCSdC??_AxJ??YvC??YnC??cAfKCV??qAxM??QdB??ShB??a#dE??WbC??EV??U|B??YjC??C`#??K~#??MdA??c#fE","CalculatedAvgSpeed":84.43636},{"TrackingAvgSpeed":-1.0,"OverspeedPercent":0,"AvgAllowedSpeed":90.0,"DistanceInMeters":2011,"Points":0.0,"Polyline":"qlbxHgy|iC[zC??Gl#??c#hE??[xC??Gj#??AL??MpA??Gj#??Iv#??CR??OrA??CZ??O|A??e#hE??W`C??CV??OvAC\\E`#AT??A\\C^Ad#UjJ??UzI??Cl#??_#bOAd#Cp#Cp#C\\C`#Cb#CTEZ??CR??[pB_#bC??w#|E??aAjG??g#vC??e#lC??a#|B??Kj#??EX??i#zC??GZ??a#`C??_AhF??[bB??SfA??u#hE??s#dE","CalculatedAvgSpeed":80.48},{"TrackingAvgSpeed":-1.0,"OverspeedPercent":82,"AvgAllowedSpeed":57.02,"DistanceInMeters":245,"Points":0.0,"Polyline":"glcxHyjwiCG\\Mr#Gf#??Gv#Cf#Af#Ab##f#?b##f#Bb#??Dj#??D`#D\\F`#Jd#Jd#Ld#","CalculatedAvgSpeed":56.475},{"TrackingAvgSpeed":-1.0,"OverspeedPercent":86,"AvgAllowedSpeed":52.73,"DistanceInMeters":1282,"Points":0.0,"Polyline":"mkcxH{tviCNf#N^NZLV??LR??JR??bA`B^r#??|#zA??f#`A??LR??HP??f#~#??P`#Tf#??NXN\\??Vn#??DL??Xr#Rb#??t#pB??Rf#??r#fB??Rh#??Pb#??LX??p#dB??HR??#D??JV??HP??`#fA??LX??j#zA??LX??n#bB??`AdC??Pd#??N^??FN??Vn#??FP??`#`A??|#|B??~#`C??Xt#??^bA??Zt#??h#vA??^~#??Nb#??h#rA??~#bC","CalculatedAvgSpeed":53.16},{"TrackingAvgSpeed":-1.0,"OverspeedPercent":41,"AvgAllowedSpeed":83.09,"DistanceInMeters":1446,"Points":0.0,"Polyline":"q|axHqzsiCTh#??Rh#??JZ??`#bA??FN??Tj#??t#jB??j#vA??rHfRPb#L^L`#J\\J^Pr#b#fB??z#dD??r#rC??nB`I??lA~E??fCbK??XjA??p#jCXdAz#xC??p#xB??fAnD??\\hA??Rr#PE","CalculatedAvgSpeed":83.82857}];
var polylines = [], points = [], behavePolylines = [];
$(function(){
var map;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: -34.397, lng: 150.644},
zoom: 8
});
}
function getRandomColor() {
var letters = '0123456789ABCDEF'.split('');
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
};
function getColor(calculated, allowed){
var diff = calculated - allowed;
if(diff <=0){
return "#0ea00f";
} else if(diff >0 && diff <= 15){
return "#ff6a00"
} else if(diff > 15){
return "#ff0000"
} else return "#000"
}
function renderTrip (trip) {
//if (!data.success) return;
// var trip = JSON.parse(data.trip);
$.each(polylines, function (e, val) {
map.removeLayer(val);
});
var tripPolyPoints = L.PolylineUtil.decode(data.POLY);
var tripPoly = L.polyline(tripPolyPoints,
{
color: "#000000",
opacity: 0.6,
weight: 4
});
tripPoly.addTo(map);
map.fitBounds(tripPoly.getBounds());
polylines.push(tripPoly);
for (var i = 0; i < trip.length; i++) {
var calculated = (trip[i].CalculatedAvgSpeed).toFixed(1);
var allowed = (trip[i].AvgAllowedSpeed).toFixed(1);
var distance = (trip[i].DistanceInMeters / 1000.0).toFixed(2);
var polylinePoints = L.PolylineUtil.decode(trip[i].Polyline);
var polyline = L.polyline(polylinePoints, {
color: getColor(calculated, allowed),
opacity: 1,
weight: 8
}).bindLabel('Średnia prędkość: ' + calculated + ' KM/H<br>Średnia dopuszczalna prędkość: '
+ allowed + ' KM/H<br>Długość odcinka: ' + distance + ' KM');
polyline.addTo(map);
polylines.push(polyline);
}
var origPolyPoints = L.PolylineUtil.decode(data.bfPoly);
var origPoly = L.polyline(origPolyPoints,
{
color: "#0000ff",
opacity: 0.5,
weight: 5
});
origPoly.addTo(map);
polylines.push(origPoly);
}
renderTrip(itm);
});
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=MY_KAY&callback=initMap"
async defer></script>
</body>
</html>
Error Message :
Uncaught (in promise) yd {message: "initMap is not a function", name:
"InvalidValueError", stack: "Error↵ at new yd message: "initMap is
not a function" name: "InvalidValueError"
Your initMap function needs to be placed in global scope so that the Map API's callback can find and call this function.
<script>
var itm = [];
var polylines = [],
points = [],
behavePolylines = [];
var map;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: { lat: -34.397, lng: 150.644 },
zoom: 8
});
}
$(function() {
function getRandomColor() {
var letters = '0123456789ABCDEF'.split('');
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
};
...
});
</script>
Please check out related thread Google Maps Javascript API not loading reliably
Hope this helps!
I wanted to display a 2D Map with Python and then do something with the coordinates of the coursor in the Python code. I cant get the coordinates to the Python Part however.
Heres my code:
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWebEngineWidgets import *
from PyQt5.QtWidgets import QWidget,QVBoxLayout, QApplication
from PyQt5.QtWebChannel import QWebChannel
import bs4
maphtml = '''
<!DOCTYPE HTML>
<!DOCTYPE HTML>
<html>
<head>
<meta name="robots" content="index, all" />
<script src="qrc:///qtwebchannel/qwebchannel.js"></script>
<title>WebGL Earth API - Side-by-side - Basic Leaflet compatibility</title>
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.css" />
<script src="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.js"></script>
<script src="http://www.webglearth.com/v2/api.js"></script>
<script>
var backend;
new QWebChannel(qt.webChannelTransport, function (channel) {
backend = channel.objects.backend;
});
function init() {
var m = {};
start_(L, 'L');
start_(WE, 'WE');
function start_(API, suffix) {
var mapDiv = 'map' + suffix;
var map = API.map(mapDiv, {
center: [51.505, -0.09],
zoom: 4,
dragging: true,
scrollWheelZoom: true,
proxyHost: 'http://srtm.webglearth.com/cgi-bin/corsproxy.fcgi?url='
});
m[suffix] = map;
//Add baselayer
API.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',{
attribution: '© OpenStreetMap contributors'
}).addTo(map);
//Add TileJSON overlay
var json = {"profile": "mercator", "name": "Grand Canyon USGS", "format": "png", "bounds": [-112.26379395, 35.98245136, -112.10998535, 36.13343831], "minzoom": 10, "version": "1.0.0", "maxzoom": 16, "center": [-112.18688965, 36.057944835, 13], "type": "overlay", "description": "", "basename": "grandcanyon", "tilejson": "2.0.0", "sheme": "xyz", "tiles": ["http://tileserver.maptiler.com/grandcanyon/{z}/{x}/{y}.png"]};
if (API.tileLayerJSON) {
var overlay2 = API.tileLayerJSON(json, map);
} else {
//If not able to display the overlay, at least move to the same location
map.setView([json.center[1], json.center[0]], json.center[2]);
}
//Add simple marker
var marker = API.marker([json.center[1], json.center[0]]).addTo(map);
marker.bindPopup(suffix, 50);
marker.openPopup();
//Print coordinates of the mouse
map.on('mousemove', function(e) {
document.getElementById('coords').innerHTML = e.latlng.lat + ', ' + e.latlng.lng;
backend.print(e.latlng.lat)
});
}
//Synchronize view
m['L'].on('move', function(e) {
var center = m['L'].getCenter();
var zoom = m['L'].getZoom();
m['WE'].setView([center['lat'], center['lng']], zoom);
});
}
</script>
<style>
html, body{padding: 0; margin: 0; overflow: hidden;}
#mapL, #mapWE {position:absolute !important; top: 0; right: 0; bottom: 0; left: 0;
background-color: #fff; position: absolute !important;}
#mapL {right: 0%;}
#mapWE {left: 100%;}
#coords {position: absolute; bottom: 0;}
</style>
</head>
<body onload="javascript:init()">
<div id="mapL"></div>
<div id="mapWE"></div>
<div id="coords"></div>
</body>
</html>
'''
class Browser(QApplication):
def __init__(self):
QApplication.__init__(self, [])
self.window = QWidget()
self.window.setWindowTitle("Serial GPS Emulator");
self.web = QWebEngineView(self.window)
self.web.setHtml(maphtml)
self.layout = QVBoxLayout(self.window)
self.layout.addWidget(self.web)
self.window.show()
self.exec()
Browser()
It would be good if the code would stay in one file but if its totally impossible to do it in one splitting it is acceptable.
I guess the first step in solving mny Problem would be to call a function from the HTML/JS part as backend.print("test") also doesnt work.
I also noticed that self.exec() Blocks the rest of the code, is there a way to execute any other code while the map is running? Thanks!
I do not see where in your code you have passed the backend.
In this case you must create a Backend class that can be injected, and for a method to be invoked it must be a slot, for this you must use the pyqtSlot() setting, the parameter that it receives depends on what you are sending it, in the case of the e.latlng is a QJsonValue. In the slot you must separate the necessary parts.
import sys
from PyQt5.QtCore import pyqtSlot, QObject, QJsonValue, pyqtSignal, QTimer
from PyQt5.QtWebChannel import QWebChannel
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtWidgets import QApplication
maphtml = '''
<!DOCTYPE HTML>
<!DOCTYPE HTML>
<html>
<head>
<meta name="robots" content="index, all" />
<script src="qrc:///qtwebchannel/qwebchannel.js"></script>
<title>WebGL Earth API - Side-by-side - Basic Leaflet compatibility</title>
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.css" />
<script src="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.js"></script>
<script src="http://www.webglearth.com/v2/api.js"></script>
<script>
var backend;
new QWebChannel(qt.webChannelTransport, function (channel) {
backend = channel.objects.backend;
console.log(backend);
});
function init() {
var m = {};
start_(L, 'L');
start_(WE, 'WE');
function start_(API, suffix) {
var mapDiv = 'map' + suffix;
var map = API.map(mapDiv, {
center: [51.505, -0.09],
zoom: 4,
dragging: true,
scrollWheelZoom: true,
proxyHost: 'http://srtm.webglearth.com/cgi-bin/corsproxy.fcgi?url='
});
m[suffix] = map;
//Add baselayer
API.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',{
attribution: '© OpenStreetMap contributors'
}).addTo(map);
//Add TileJSON overlay
var json = {"profile": "mercator", "name": "Grand Canyon USGS", "format": "png", "bounds": [-112.26379395, 35.98245136, -112.10998535, 36.13343831], "minzoom": 10, "version": "1.0.0", "maxzoom": 16, "center": [-112.18688965, 36.057944835, 13], "type": "overlay", "description": "", "basename": "grandcanyon", "tilejson": "2.0.0", "sheme": "xyz", "tiles": ["http://tileserver.maptiler.com/grandcanyon/{z}/{x}/{y}.png"]};
if (API.tileLayerJSON) {
var overlay2 = API.tileLayerJSON(json, map);
} else {
//If not able to display the overlay, at least move to the same location
map.setView([json.center[1], json.center[0]], json.center[2]);
}
//Add simple marker
var marker = API.marker([json.center[1], json.center[0]]).addTo(map);
marker.bindPopup(suffix, 50);
marker.openPopup();
//Print coordinates of the mouse
map.on('mousemove', function(e) {
document.getElementById('coords').innerHTML = e.latlng.lat + ', ' + e.latlng.lng;
backend.print(e.latlng)
});
}
//Synchronize view
m['L'].on('move', function(e) {
var center = m['L'].getCenter();
var zoom = m['L'].getZoom();
m['WE'].setView([center['lat'], center['lng']], zoom);
});
}
</script>
<style>
html, body{padding: 0; margin: 0; overflow: hidden;}
#mapL, #mapWE {position:absolute !important; top: 0; right: 0; bottom: 0; left: 0;
background-color: #fff; position: absolute !important;}
#mapL {right: 0%;}
#mapWE {left: 100%;}
#coords {position: absolute; bottom: 0;}
</style>
</head>
<body onload="javascript:init()">
<div id="mapL"></div>
<div id="mapWE"></div>
<div id="coords"></div>
</body>
</html>
'''
class Backend(QObject):
positionChanged = pyqtSignal(float, float)
def __init__(self, parent=None):
QObject.__init__(self, parent)
self.position = None, None
self.timer = QTimer(self)
self.timer.setInterval(1000)
self.timer.timeout.connect(self.on_timeout)
#pyqtSlot(QJsonValue)
def print(self, val):
coords = val.toObject()
lat, lng = (coords[key].toDouble() for key in ("lat", "lng"))
self.position = lat, lng
if not self.timer.isActive():
self.timer.start()
def on_timeout(self):
self.positionChanged.emit(*self.position)
def foo(lat, lng):
# this function will be called every second.
print(lat, lng)
if __name__ == '__main__':
app = QApplication(sys.argv)
view = QWebEngineView()
view.setWindowTitle("Serial GPS Emulator");
backend = Backend(view)
backend.positionChanged.connect(foo)
channel = QWebChannel()
channel.registerObject('backend', backend)
view.page().setWebChannel(channel)
view.setHtml(maphtml)
view.show()
sys.exit(app.exec_())
here is my script, I'm currently having a bad time with leaflet, it is taking substantial amounts of time to load my markers yet I'm only playing with up to 200-500 at a time and can't seem to find the reason why.
Markers are pulled from an API and stored into an array then plotted onto the map upon clicking a section on the map, see for yourself on the live demo, it works fine until loading markers then it starts to lag a lot when zooming
If anybody has a solution for me it would be much appreciated as I intend to have a lot more markers than it is currently pulling.
var postcode;
var police_api_dates = [
"&date=2017-03",
];
var completed_requests = 0;
var police_api_base_url = "https://data.police.uk/api/crimes-street/all-crime?poly=";
var crimes = [];
var count = 0;
var mymap = L.map('map').setView([53.7983587, -1.6191674], 11);
mymap.createPane('labels');
mymap.getPane('labels').style.zIndex = 650;
mymap.getPane('labels').style.pointerEvents = 'none';
var positron = L.tileLayer('http://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png', {
attribution: '©OpenStreetMap, ©CartoDB'
}).addTo(mymap);
var positronLabels = L.tileLayer('http://{s}.basemaps.cartocdn.com/light_only_labels/{z}/{x}/{y}.png', {
attribution: '©OpenStreetMap, ©CartoDB',
pane: 'labels'
}).addTo(mymap);
L.tileLayer('https://api.mapbox.com/styles/v1/adam97x/cjavcj1680vgz2sqshn70q5pg/tiles/256/{z}/{x}/{y}?access_token=pk.eyJ1IjoiYWRhbTk3eCIsImEiOiJjamF2Y2k1NmswYzhuMnZtazlpNXU2NDExIn0.RifBBI5nelL-4d21mkn7Wg', {
maxZoom: 18,
attribution: 'Map data © OpenStreetMap contributors, ' +
'CC-BY-SA, ' +
'Imagery © Mapbox',
id: 'mapbox.streets'
}).addTo(mymap);
// control that shows state info on hover
var info = L.control();
info.onAdd = function (mymap) {
this._div = L.DomUtil.create('div', 'info');
this.update();
return this._div;
};
info.update = function (properties) {
this._div.innerHTML = '<h4>Highlighted Postcode</h4>' + (properties ?
'<b> Postcode: ' + properties.Name
: 'Hover over a state');
};
info.addTo(mymap);
function style(feature) {
return {
fillColor: 'grey',
weight: 2,
opacity: 1,
color: 'white',
dashArray: '3',
fillOpacity: 0.5
};
}
L.geoJson(statesdata, {style: style}).addTo(mymap);
function highlightFeature(e) {
var layer = e.target;
layer.setStyle({
weight: 5,
opacity: 1,
color: '#000',
dashArray: '',
fillOpacity: 0.7
});
if (!L.Browser.ie && !L.Browser.opera && !L.Browser.edge) {
layer.bringToFront();
}
info.update(layer.feature.properties);
postcode = layer.feature.properties.Name.substr(2)-1;
console.log(postcode);
}
/*global statesdata*/
var geojson;
function resetHighlight(e) {
geojson.resetStyle(e.target);
info.update();
}
function zoomFeature(e) {
mymap.fitBounds(e.target.getBounds());
var colonString = statesdata
.features[postcode]
.geometry
.coordinates[0]
.map(pair => pair.reverse().join())
.join(':');
for (var a = 0; a < 1; a++){
var request = police_api_base_url + colonString + police_api_dates[a]
get_JSON(request, JSON_callback);
}
}
function onEachFeature(feature, layer) {
layer.on({
mouseover: highlightFeature,
mouseout: resetHighlight,
click: zoomFeature
});
}
geojson = L.geoJson(statesdata, {
style: style,
onEachFeature: onEachFeature
}).addTo(mymap);
geojson.eachLayer(function (layer) {
layer.bindPopup(layer.feature.properties.Name);
});
function JSON_callback(data){
completed_requests++;
var data_len = data.length;
if (data[0] != undefined){
for (var i = 0; i < data_len; i++){
cat = data[i]["category"];
lat = data[i]["location"]["latitude"];
lng = data[i]["location"]["longitude"];
if (cat in crimes) {
crimes[cat]++;
} else {
crimes[cat] = 1;
}
create_marker(lat, lng);
}
}
if (completed_requests == 1){
console.log("Requests done");
console.log(crimes);
}
}
function create_crime_markers(lat, lng, cat){
show_by_id("num_of_crimes_load_img");
show_by_id("popular_crime_load_img");
completed_requests = 0;
num_of_crimes = 0;
crimes = {};;
for (var a = 0; a < 1; a++){
var request = police_api_base_url + lat + "&lng=" + lng + police_api_dates[a]
get_JSON(request, JSON_callback);
}
}
var current_lat_lng = [];
function create_marker(lat, lng, title){
current_lat_lng.push(lat, lng, cat);
chunksize = 3;
var chunks = [];
current_lat_lng.forEach((item)=>{
if(!chunks.length || chunks[chunks.length-1].length == chunksize)
chunks.push([]);
chunks[chunks.length-1].push(item);
});
var markers = L.markerClusterGroup({
chunkedloading: true,
spiderfyOnMaxZoom: true,
showCoverageOnHover: false,
zoomToBoundsOnClick: true,
spiderfyDistanceMultiplier: 2.4
});
var markerList = [];
for (var f = 0; f < chunks.length; f++) {
var marker = new L.circleMarker([chunks[f][0],chunks[f][1]])
markerList.push(marker);
}
markers.addLayers(markerList);
mymap.addLayer(markers);
}
body { margin:0; padding:0; }
#map { position:absolute; top:0; bottom:0; width:100%; }
.info { padding: 6px 8px; font: 14px/16px Arial, Helvetica, sans-serif; background: white; background: rgba(255,255,255,0.8); box-shadow: 0 0 15px rgba(0,0,0,0.2); border-radius: 5px; } .info h4 { margin: 0 0 5px; color: #777; }
<html>
<head>
<meta charset=utf-8 />
<title>KML Data</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.2.0/dist/leaflet.css" />
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster#1.2.0/dist/MarkerCluster.Default.css" />
<script src="https://unpkg.com/leaflet#1.2.0/dist/leaflet.js"></script>
<script type="text/javascript" src="https://project-adam97.c9users.io/asset/bd.js"></script>
<script src="https://project-adam97.c9users.io/asset/requests.js"></script>
</head>
<body>
<script> src='https://api.mapbox.com/mapbox.js/plugins/leaflet-omnivore/v0.2.0/leaflet-omnivore.min.js'></script>
<script src="https://unpkg.com/leaflet.markercluster#1.2.0/dist/leaflet.markercluster.js"></script>
<div id='map'></div>
</body>
</html>