L.GPX is not a constructor - leaflet

i'm looking for import GPX file inside my Leaflet map
but when i try the site it respond with L.GPX is not a constructor
i only have that in my head
<script src="https://unpkg.com/leaflet#1.7.1/dist/leaflet.js"></script>
and that inside body
<div id="map"></div>
<script>
var sites = {!! json_encode($markers) !!};
var map = L.map('map').setView([{{ config('leaflet.map_center_latitude') }}, {{ config('leaflet.map_center_longitude') }}], {{ config('leaflet.zoom_level') }});
L.tileLayer('https://api.maptiler.com/maps/streets/{z}/{x}/{y}#2x.png?key=2Qw6dd02HLfOXS3LDGMP', {
attribution: '© MapTiler © OpenStreetMap contributors'
}).addTo(map);
var marker;
sites.forEach(element => {
marker = L.marker([element[0], element[1]]).addTo(map);
});
var gpx = '/resources/gpx/pont.gpx'; // URL to your GPX file or the GPX itself
new L.GPX(gpx, {
async: true,
polyline_options: {
color: '#ff0000',
}
}
).on('loaded', function(e) {
map.fitBounds(e.target.getBounds());
}).addTo(map);
</script>

You have to load the plugin before you can use it:
Usage
First, include the Leaflet.js and Leaflet-GPX scripts in your HTML
page:
As described, add the following line, in your header or before your script
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-gpx/1.4.0/gpx.min.js"></script>

Related

How to add I3SLoader 3dtile layer (deck.gl) integrated with mapbox

I am trying to add arcgis 3d layer in mapbox with DeckGL. But I have this error (Uncaught TypeError: Tile3DLayer is not a constructor)
If I could bring data from arcgis sceneserver ,I try add two maps like compare(mapbox gl swipe tool) them.
maybe there are different ways to solve this problem. Taking the arcgis data I need and calling two maps on the same web page. Then make a presentation with the comparison tool between these maps.
<html>
<head>
<title>deck.gl + Mapbox Integration</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src="https://unpkg.com/deck.gl#^6.2.0/deckgl.min.js"></script>
<script src="https://api.tiles.mapbox.com/mapbox-gl-js/v0.50.0/mapbox-gl.js"></script>
<link rel="stylesheet" type="text/css" href="https://api.tiles.mapbox.com/mapbox-gl-js/v0.50.0/mapbox-gl.css">
<script src="https://unpkg.com/#loaders.gl/i3s#2.1.6/dist/dist.min.js"></script>
</head>
<body>
<div id="map" style="width: 100vw; height: 100vh"></div>
</body>
<script type="text/javascript">
const { MapboxLayer, ScatterplotLayer } = deck;
// Get a mapbox API access token
mapboxgl.accessToken = 'pk.eyJ1IjoidWJlcmRhdGEiLCJhIjoiY2pudzRtaWloMDAzcTN2bzN1aXdxZHB5bSJ9.2bkj3IiRC8wj3jLThvDGdA';
// Initialize mapbox map
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/light-v9',
center: [-74.50, 40],
zoom: 9
});
const {DeckGL, Tile3DLayer} = deck;
const {I3SLoader} = loaders;
const deckgl = new DeckGL({
controller: true,
layers: [
new Tile3DLayer({
id: 'tile-3d-layer',
data:
'https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/SanFrancisco_Bldgs/SceneServer/layers/0',
loader: I3SLoader,
onTilesetLoad: (tileset) => {
const {zoom, cartographicCenter} = tileset;
const [longitude, latitude] = cartographicCenter;
const viewState = {
...deckgl.viewState,
zoom: zoom + 2.5,
longitude,
latitude
};
deckgl.setProps({initialViewState: viewState});
}
})
]
});
map.on('load', () => {
map.addLayer(deckgl);
});
</script>
</html>
I'm using React, the core code is here, hope I can help you.
// import { MapboxLayer } from '#deck.gl/mapbox';
// import {I3SLoader} from '#loaders.gl/i3s';
// import { Tile3DLayer } from '#deck.gl/geo-layers';
// import mapboxgl from 'mapbox-gl';
mapboxgl.accessToken = 'your-token';
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v11',
center: [-122.51473530281777,37.70463582140094],
zoom: 13
});
const layer = new MapboxLayer({
id:'i3s',
type: Tile3DLayer,
data: 'https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/SanFrancisco_Bldgs/SceneServer/layers/0',
loader: I3SLoader
});
map.on('load', () => {
map.resize();
map.addLayer(layer);
});

How to use supercluster

I am new to mapbox.
I need to use the supercluster project of mapbox in order to plot 6 millions of gps in a map.
i tried to use the demo in localhost but i only get an empty map !?
this is my code in index.html :
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Supercluster Leaflet demo</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.3/leaflet.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.3/leaflet.js"></script>
<link rel="stylesheet" href="cluster.css" />
<style>
html, body, #map {
height: 100%;
margin: 0;
}
</style>
</head>
<body>
<div id="map"></div>
<script src="index.js"></script>
<script src="https://unpkg.com/supercluster#3.0.2/dist/supercluster.min.js">
var index = supercluster({
radius: 40,
maxZoom: 16
});
index.load(GeoObs.features);
index.getClusters([-180, -85, 180, 85], 2);
</script>
</body>
</html>
Note : GeoObs is my geojson file
what is wrong ?
FWIW here is a self-contained example of how to use supercluster, without a Web Worker. It is also simply based on the repo demo.
var map = L.map('map').setView([0, 0], 0);
// Empty Layer Group that will receive the clusters data on the fly.
var markers = L.geoJSON(null, {
pointToLayer: createClusterIcon
}).addTo(map);
// Update the displayed clusters after user pan / zoom.
map.on('moveend', update);
function update() {
if (!ready) return;
var bounds = map.getBounds();
var bbox = [bounds.getWest(), bounds.getSouth(), bounds.getEast(), bounds.getNorth()];
var zoom = map.getZoom();
var clusters = index.getClusters(bbox, zoom);
markers.clearLayers();
markers.addData(clusters);
}
// Zoom to expand the cluster clicked by user.
markers.on('click', function(e) {
var clusterId = e.layer.feature.properties.cluster_id;
var center = e.latlng;
var expansionZoom;
if (clusterId) {
expansionZoom = index.getClusterExpansionZoom(clusterId);
map.flyTo(center, expansionZoom);
}
});
// Retrieve Points data.
var placesUrl = 'https://cdn.rawgit.com/mapbox/supercluster/v4.0.1/test/fixtures/places.json';
var index;
var ready = false;
jQuery.getJSON(placesUrl, function(geojson) {
// Initialize the supercluster index.
index = supercluster({
radius: 60,
extent: 256,
maxZoom: 18
}).load(geojson.features); // Expects an array of Features.
ready = true;
update();
});
function createClusterIcon(feature, latlng) {
if (!feature.properties.cluster) return L.marker(latlng);
var count = feature.properties.point_count;
var size =
count < 100 ? 'small' :
count < 1000 ? 'medium' : 'large';
var icon = L.divIcon({
html: '<div><span>' + feature.properties.point_count_abbreviated + '</span></div>',
className: 'marker-cluster marker-cluster-' + size,
iconSize: L.point(40, 40)
});
return L.marker(latlng, {
icon: icon
});
}
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map);
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.3.1/dist/leaflet.css" integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" crossorigin="" />
<link rel="stylesheet" href="https://cdn.rawgit.com/mapbox/supercluster/v4.0.1/demo/cluster.css" />
<script src="https://unpkg.com/leaflet#1.3.1/dist/leaflet-src.js" integrity="sha512-IkGU/uDhB9u9F8k+2OsA6XXoowIhOuQL1NTgNZHY1nkURnqEGlDZq3GsfmdJdKFe1k1zOc6YU2K7qY+hF9AodA==" crossorigin=""></script>
<script src="https://unpkg.com/supercluster#4.0.1/dist/supercluster.js"></script>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<div id="map" style="height: 180px"></div>
var map = L.map('map').setView([0, 0], 0);
// Empty Layer Group that will receive the clusters data on the fly.
var markers = L.geoJSON(null, {
pointToLayer: createClusterIcon
}).addTo(map);
// Update the displayed clusters after user pan / zoom.
map.on('moveend', update);
function update() {
if (!ready) return;
var bounds = map.getBounds();
var bbox = [bounds.getWest(), bounds.getSouth(), bounds.getEast(), bounds.getNorth()];
var zoom = map.getZoom();
var clusters = index.getClusters(bbox, zoom);
markers.clearLayers();
markers.addData(clusters);
}
// Zoom to expand the cluster clicked by user.
markers.on('click', function(e) {
var clusterId = e.layer.feature.properties.cluster_id;
var center = e.latlng;
var expansionZoom;
if (clusterId) {
expansionZoom = index.getClusterExpansionZoom(clusterId);
map.flyTo(center, expansionZoom);
}
});
// Retrieve Points data.
var placesUrl = 'https://cdn.rawgit.com/mapbox/supercluster/v4.0.1/test/fixtures/places.json';
var index;
var ready = false;
jQuery.getJSON(placesUrl, function(geojson) {
// Initialize the supercluster index.
index = supercluster({
radius: 60,
extent: 256,
maxZoom: 18
}).load(geojson.features); // Expects an array of Features.
ready = true;
update();
});
function createClusterIcon(feature, latlng) {
if (!feature.properties.cluster) return L.marker(latlng);
var count = feature.properties.point_count;
var size =
count < 100 ? 'small' :
count < 1000 ? 'medium' : 'large';
var icon = L.divIcon({
html: '<div><span>' + feature.properties.point_count_abbreviated + '</span></div>',
className: 'marker-cluster marker-cluster-' + size,
iconSize: L.point(40, 40)
});
return L.marker(latlng, {
icon: icon
});
}
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map);
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.3.1/dist/leaflet.css" integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" crossorigin="" />
<link rel="stylesheet" href="https://cdn.rawgit.com/mapbox/supercluster/v4.0.1/demo/cluster.css" />
<script src="https://unpkg.com/leaflet#1.3.1/dist/leaflet-src.js" integrity="sha512-IkGU/uDhB9u9F8k+2OsA6XXoowIhOuQL1NTgNZHY1nkURnqEGlDZq3GsfmdJdKFe1k1zOc6YU2K7qY+hF9AodA==" crossorigin=""></script>
<script src="https://unpkg.com/supercluster#4.0.1/dist/supercluster.js"></script>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<div id="map" style="height: 180px"></div>
var map = L.map('map').setView([0, 0], 0);
// Empty Layer Group that will receive the clusters data on the fly.
var markers = L.geoJSON(null, {
pointToLayer: createClusterIcon
}).addTo(map);
// Update the displayed clusters after user pan / zoom.
map.on('moveend', update);
function update() {
if (!ready) return;
var bounds = map.getBounds();
var bbox = [bounds.getWest(), bounds.getSouth(), bounds.getEast(), bounds.getNorth()];
var zoom = map.getZoom();
var clusters = index.getClusters(bbox, zoom);
markers.clearLayers();
markers.addData(clusters);
}
// Zoom to expand the cluster clicked by user.
markers.on('click', function(e) {
var clusterId = e.layer.feature.properties.cluster_id;
var center = e.latlng;
var expansionZoom;
if (clusterId) {
expansionZoom = index.getClusterExpansionZoom(clusterId);
map.flyTo(center, expansionZoom);
}
});
// Retrieve Points data.
var placesUrl = 'https://dev.infrapedia.com/api/assets/map/facilities.points.json';
var index;
var ready = false;
jQuery.getJSON(placesUrl, function(geojson) {
// Initialize the supercluster index.
index = supercluster({
radius: 60,
extent: 256,
maxZoom: 18
}).load(geojson.features); // Expects an array of Features.
ready = true;
update();
});
function createClusterIcon(feature, latlng) {
if (!feature.properties.cluster) return L.marker(latlng);
var count = feature.properties.point_count;
var size =
count < 100 ? 'small' :
count < 1000 ? 'medium' : 'large';
var icon = L.divIcon({
html: '<div><span>' + feature.properties.point_count_abbreviated + '</span></div>',
className: 'marker-cluster marker-cluster-' + size,
iconSize: L.point(40, 40)
});
return L.marker(latlng, {
icon: icon
});
}
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map);
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.3.1/dist/leaflet.css" integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" crossorigin="" />
<link rel="stylesheet" href="https://cdn.rawgit.com/mapbox/supercluster/v4.0.1/demo/cluster.css" />
<script src="https://unpkg.com/leaflet#1.3.1/dist/leaflet-src.js" integrity="sha512-IkGU/uDhB9u9F8k+2OsA6XXoowIhOuQL1NTgNZHY1nkURnqEGlDZq3GsfmdJdKFe1k1zOc6YU2K7qY+hF9AodA==" crossorigin=""></script>
<script src="https://unpkg.com/supercluster#4.0.1/dist/supercluster.js"></script>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<div id="map" style="height: 180px"></div>
I Solved my issue.
to use the supercluster project you need :
1) download and install : node and npm
2) with npm install supercluster: npm i supercluster
then you will get a folder named node_modules in which you will find supercluster folder under it copy the folder named dist (node_modules>supercluster>dist)
3) download from github the project supercluster here you will get a folder named supercluster-master past in it the folder dist copied in step 2)
Now you can test it by selecting index.html into your browser (supercluster-master>demo>index.html)
if you want to test another JSON or GEOJSON file just:
1) put this file under fixtures folder
(supercluster-master>test>fixtures)
then
2) open worker.js (supercluster-master>demo>worker.js) and change the first variable of the geojson function to point on that file
example :
getJSON('../test/fixtures/myFile.geojson', function (geojson) {
Alternatively
you can use the super-cluster algorithme directley in mapbox gl js mapBox gl js example or with jupyter version;mapbox-jupyter mapbox-jupyter example

Leaflet zooms so now and than too much on clicking a cluster

Leaflet zooms so now and than too much on clicking a cluster.
A small part of 1 marker is shown on the right and a small part from the other marker is shown on the left side of the map.
My workaround is counting markers in scope and re-adjust the zoomlevel when the counter = 0.
Shouldn't that be in the zoomcalculation of leaflet?
The zoom correction:
mcg.on('clusterclick', function () {
if (markersInScope == 0) {
var zoom = map.getZoom();
map.setZoom(zoom - 1);
}
});
You could try adjusting the zoom to fit the bounds of the mcg and add some padding
mcg.on('clusterclick', function () {
map.fitBounds(mcg.getBounds().pad(0.5));
}
});
If you add the markers to a featureGroup, the bounds for the group will available to you:
Here is a sample file from Leaflet:
<!DOCTYPE html>
<html>
<head>
<title>Leaflet debug page</title>
<link rel="stylesheet" href="../../dist/leaflet.css" />
<link rel="stylesheet" href="../css/screen.css" />
<script src="../leaflet-include.js"></script>
</head>
<body>
<div id="map" style="width: 600px; height: 600px; border: 1px solid #ccc"></div>
<button onclick="geojsonLayerBounds();">Show GeoJSON layer bounds</button>
<button onclick="featureGroupBounds();">Show feature group bounds</button>
<script src="geojson-sample.js"></script>
<script>
var osmUrl = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
osmAttrib = '© OpenStreetMap contributors',
osm = L.tileLayer(osmUrl, {maxZoom: 18, attribution: osmAttrib}),
rectangle,
featureGroup;
var map = new L.Map('map', {
center: new L.LatLng(0.78, 102.37),
zoom: 7,
layers: [osm]
});
var geojson = L.geoJson(geojsonSample, {
style: function (feature) {
return {color: feature.properties.color};
},
onEachFeature: function (feature, layer) {
var popupText = 'geometry type: ' + feature.geometry.type;
if (feature.properties.color) {
popupText += '<br/>color: ' + feature.properties.color
}
layer.bindPopup(popupText);
}
});
geojson.addLayer(new L.Marker(new L.LatLng(2.745530718801952, 105.194091796875)))
var eye1 = new L.Marker(new L.LatLng(-0.7250783020332547, 101.8212890625));
var eye2 = new L.Marker(new L.LatLng(-0.7360637370492077, 103.2275390625));
var nose = new L.Marker(new L.LatLng(-1.3292264529974207, 102.5463867187));
var mouth = new L.Polyline([
new L.LatLng(-1.3841426927920029, 101.7333984375),
new L.LatLng(-1.6037944300589726, 101.964111328125),
new L.LatLng(-1.6806671337507222, 102.249755859375),
new L.LatLng(-1.7355743631421197, 102.67822265625),
new L.LatLng(-1.5928123762763, 103.0078125),
new L.LatLng(-1.3292264529974207, 103.3154296875)
]);
map.addLayer(eye1).addLayer(eye2).addLayer(nose).addLayer(mouth);
featureGroup = new L.FeatureGroup([eye1, eye2, nose, mouth]);
map.addLayer(geojson);
map.addLayer(featureGroup);
function geojsonLayerBounds() {
if (rectangle) {
rectangle.setBounds(geojson.getBounds());
} else {
rectangle = new L.Rectangle(geojson.getBounds());
map.addLayer(rectangle);
}
}
function featureGroupBounds() {
if (rectangle) {
rectangle.setBounds(featureGroup.getBounds());
} else {
rectangle = new L.Rectangle(featureGroup.getBounds());
map.addLayer(rectangle);
}
}
</script>
</body>
</html>

Markers aren't working properly when I use them on a component

So I start using leaflet on my site, and I manage to make a search in which with the name of my items, I could show them. the problem is that I need to display information on click, but my markers aren't clickable.
here is my component:
<template>
<div id="mapid" style="width: 600px; height: 400px"></div>
</template>
<script>
var swal = require('sweetalert');
var config = require('../../config.js');
var Vue = require('vue');
name: 'mapOrganization',
data: function(){
return {
L : {},
}
},
ready: function(){
var L = require('../../lib/leaflet/leaflet.js')
L.Icon.Default.imagePath = '../../lib/leaflet/images';
this.initMap();
}
methods: {
initMap: function(organizations) {
var mymap = L.map('mapid').setView([51.505, -0.09], 13);
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpandmbXliNDBjZWd2M2x6bDk3c2ZtOTkifQ._QA7i5Mpkd_m30IGElHziw', {
maxZoom: 18,
attribution: 'Map data © OpenStreetMap contributors, ' +
'CC-BY-SA, ' +
'Imagery © Mapbox',
id: 'mapbox.streets'
}).addTo(mymap);
L.marker([51.5, -0.09]).addTo(mymap).bindPopup("<b>Hello world!</b><br />I am a popup.").openPopup();
L.circle([51.508, -0.11], 500, {
color: 'red',
fillColor: '#f03',
fillOpacity: 0.5
}).addTo(mymap).bindPopup("I am a circle.");
L.polygon([
[51.509, -0.08],
[51.503, -0.06],
[51.51, -0.047]
]).addTo(mymap).bindPopup("I am a polygon.");
var popup = L.popup();
function onMapClick(e) {
popup
.setLatLng(e.latlng)
.setContent("dasd" + e.latlng.toString())
.openOn(mymap);
}
mymap.on('click', onMapClick);
}
}
I have try with the Option {clickable: true}, still not working. I'm using the simple example leaflet give on start.

OSM leafleft JS Getting the center and radius of an editable circle

I am using OSM using layer Leaflet Js.I am trying to edit the circle using the Leaflet.Editable.js. I think, getting the circle and the radius using the 'editable:vertex:dragend' event is not a right approach.
Is there any other way to get the circle center and radius after dragging it.
Here is my apprach
<link href="https://leafletjs-cdn.s3.amazonaws.com/content/leaflet/master/leaflet.css" rel="stylesheet" type="text/css" />
<script src="https://leafletjs-cdn.s3.amazonaws.com/content/leaflet/master/leaflet.js"></script>
<script src="Leaflet.Editable.js"></script>
<style type="text/css">
#mapdiv { height: 500px; }
</style>
<div id="mapdiv"></div>
<script type="text/javascript">
var map = L.map('mapdiv', {editable: true}).setView([23.2599333, 77.41261499999996], 13);
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors',
maxZoom: 30
}).addTo(map);
L.EditControl = L.Control.extend({
options: {
position: 'topleft',
callback: null,
kind: '',
html: ''
},
onAdd: function (map) {
var container = L.DomUtil.create('div', 'leaflet-control leaflet-bar'),
link = L.DomUtil.create('a', '', container);
link.href = '#';
link.title = 'Create a new ' + this.options.kind;
link.innerHTML = this.options.html;
L.DomEvent.on(link, 'click', L.DomEvent.stop)
.on(link, 'click', function () {
window.LAYER = this.options.callback.call(map.editTools);
}, this);
return container;
}
});
var circle = L.circle([23.2599333, 77.41261499999996], {radius: 1000}).addTo(map);
circle.enableEdit();
circle.on('dblclick', L.DomEvent.stop).on('dblclick', circle.toggleEdit);
//circle.on('editable:vertex:drag', function (e) {
map.on('editable:vertex:dragend', function (e) {
//alert(e.vertex.latlng);
circle.setLatLng(e.vertex.latlng);
alert(circle.getRadius());
});
</script>
Any help on this regard or the best approach will be really helpful.
Yes, I would suggest using
map.on('editable:drawing:move', function (e) {
console.log(circle.getLatLng())
console.log(circle.getRadius());
});
This works for either dragging the vertex on the outer edge of the circle, or drags of the entire circle from the center marker.