I am having trouble getting jsonp to work for a data serving website. Below is my script that will plot data points on a leaflet map as long as they are in the same domain. I need to take it a step further by using jsonp. I am having trouble understanding jsonp tutorials, especially with understanding how to deal with the response of the json file. This is my first time trying to use this method, and I have not be successful as I still don't fully understand js/html that well. Any help would be great as I think I am just a few lines of code from being able to get this to work properly. Thanks.
<html>
<head>
<meta charset="utf-8"/>
<title>A Leaflet map!</title>
<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>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<style>
#map{ width: 1000px; height: 600px; }
</style>
</head>
<body>
<div id="map"></div>
<script>
var map = L.map('map',{center: [35, -121],zoom: 7});
var myStyle = {"color": "#ff7800", "weight": 5, "opacity": 0.65};
L.tileLayer('http://server.arcgisonline.com/ArcGIS/rest/services/Ocean_Basemap/MapServer/tile/{z}/{y}/{x}', {attribution: 'Tiles © Esri — Sources: GEBCO, NOAA, CHS, OSU, UNH, CSUMB, National Geographic, DeLorme, NAVTEQ, and Esri'}).addTo(map);
$.getJSON("http://localhost:8000/erdCalCOFIcufes.geojson", function(data) {
L.geoJson(data, {
style: myStyle
}).addTo(map);
})
</script>
</body>
</html>
Note that it is hosted locally as detailed below. The website I need to use is here...
https://coastwatch.pfeg.noaa.gov/erddap/tabledap/erdCalCOFIcufes.geoJson?longitude,latitude,sardine_eggs&cruise=%22201504%22&sardine_eggs%3E=0&.draw=markers&.marker=5%7C5&.color=0x000000&.colorBar=%7C%7C%7C%7C%7C&.bgColor=0xffccccff
Here is what is looks like without a proper jsonp to grab data to plot. Currently, I have been able to grab the data by hosting the scripts in the same domain as the geojson file using the following...
python -m SimpleHTTPServer
This was more for proof of concept and wont fit my needs.
<html>
<head>
<meta charset="utf-8"/>
<title>A Leaflet map!</title>
<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>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<style>
#map{ width: 1000px; height: 600px; }
</style>
</head>
<body>
<div id="map"></div>
<script>
var map = L.map('map',{center: [35, -121],zoom: 7});
var myStyle = {"color": "#ff7800", "weight": 5, "opacity": 0.65};
L.tileLayer('http://server.arcgisonline.com/ArcGIS/rest/services/Ocean_Basemap/MapServer/tile/{z}/{y}/{x}', {attribution: 'Tiles © Esri — Sources: GEBCO, NOAA, CHS, OSU, UNH, CSUMB, National Geographic, DeLorme, NAVTEQ, and Esri'}).addTo(map);
$.getJSON("http://localhost:8000/erdCalCOFIcufes.geojson", function(data) {
L.geoJson(data, {
style: myStyle
}).addTo(map);
})
</script>
</body>
</html>
The geojson file looks like the following. I cut out a lot of points to make it more digestible.
{
"type": "FeatureCollection",
"propertyNames": ["sardine_eggs"],
"propertyUnits": ["count"],
"features": [
{"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-123.3226, 38.1476] },
"properties": {
"sardine_eggs": 0 }
},
{"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-123.3527, 38.1785] },
"properties": {
"sardine_eggs": 1 }
},
{"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-123.369, 38.238] },
"properties": {
"sardine_eggs": 0 }
},
{"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-117.3725, 32.6873] },
"properties": {
"sardine_eggs": 0 }
},
{"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-117.2973, 32.6538] },
"properties": {
"sardine_eggs": 0 }
}
],
"bbox": [-126.5296, 29.8483, -117.2931, 43.7501]
}
Related
I know I can add icons on Leaflet using the following logic:
const geojson = {
"name": "interseccao_circulo",
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
},
"geometry": {
"type": "MultiPoint",
"coordinates": [
[
-46.62831244066412,
-23.551014464955063
]
]
}
},
{
"type": "Feature",
"properties": {
},
"geometry": {
"type": "MultiPoint",
"coordinates": [
[
-46.63242614612176,
-23.55277865770234
]
]
}
}
]
}
var mymap = L.map('mapdiv', {
center:[-23.552778, -46.632426],
zoom:16,
maxZoom:20,
zoomControl:false,
attributionControl:false
});
var lyrOSRHOT = L.tileLayer.provider('OpenStreetMap.HOT');
mymap.addLayer(lyrOSRHOT);
var icons = new L.Icon({
iconUrl: "https://i.imgur.com/ZcGeIVz.png",
iconSize: [40, 40],
});
let lat = geojson.features[0].geometry.coordinates[0][1]
let lng = geojson.features[0].geometry.coordinates[0][0]
let lat2 = geojson.features[1].geometry.coordinates[0][1]
let lng2 = geojson.features[1].geometry.coordinates[0][0]
L.marker([lat, lng], {icon: icons}).addTo(mymap);
L.marker([lat2, lng2], {icon: icons}).addTo(mymap);
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet-src.min.js" integrity="sha512-XQr+/1RXvYozXiwrumwtu3lqQmVwZ8nkLUrC/mc3HBHw4Imh++RXjwtLQFuOz3i65j9CSfKt50x6w/uUY2ovOQ==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-providers/1.12.0/leaflet-providers.min.js" integrity="sha512-LixflAm9c0/qONbz9F1Ept+QJ6QBpb7wUlPuyv1EHloTVgwSK8j3yMV3elnElGQcv7Y5QTFlF/FqyeE/N4LnKQ==" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet.css" integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==" crossorigin="anonymous" />
<div id="mapdiv" style="height:100vh; width: 100vw"></div>
However, I'd like to make it work when I draw the points using the L.geoJSON function. Something like the following:
const geojson = {
"name": "interseccao_circulo",
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
},
"geometry": {
"type": "MultiPoint",
"coordinates": [
[
-46.62831244066412,
-23.551014464955063
]
]
}
},
{
"type": "Feature",
"properties": {
},
"geometry": {
"type": "MultiPoint",
"coordinates": [
[
-46.63242614612176,
-23.55277865770234
]
]
}
}
]
}
var mymap = L.map('mapdiv', {
center:[-23.552778, -46.632426],
zoom:16,
maxZoom:20,
zoomControl:false,
attributionControl:false
});
var lyrOSRHOT = L.tileLayer.provider('OpenStreetMap.HOT');
mymap.addLayer(lyrOSRHOT);
var icons = new L.Icon({
iconUrl: "https://i.imgur.com/ZcGeIVz.png",
iconSize: [40, 40],
});
L.geoJSON(geojson, {icon: icons} ).addTo(mymap);
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet-src.min.js" integrity="sha512-XQr+/1RXvYozXiwrumwtu3lqQmVwZ8nkLUrC/mc3HBHw4Imh++RXjwtLQFuOz3i65j9CSfKt50x6w/uUY2ovOQ==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-providers/1.12.0/leaflet-providers.min.js" integrity="sha512-LixflAm9c0/qONbz9F1Ept+QJ6QBpb7wUlPuyv1EHloTVgwSK8j3yMV3elnElGQcv7Y5QTFlF/FqyeE/N4LnKQ==" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet.css" integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==" crossorigin="anonymous" />
<div id="mapdiv" style="height:100vh; width: 100vw"></div>
I've tried running it with L.geoJSON(geojson, {icon: icons} ).addTo(mymap), but it doesn't seem to recognize {icon: icons} as the function L.marker does (it's plotting the default Leaflet marker instead)... Is there any way I can draw icons with the function L.geoJSON when I use LeafLet?
I ended up finding the solution to this problem using the pointToLayer object instead of trying to use the icon object inside L.geoJSON. As it's written on the Leaflet geoJSON documentation, the accepted options inside it are only: style, pointToLayer, onEachFeature and filter. The icon option is not accepted inside the Leaflet geoJSON function and it should be used inside the pointToLayer object instead... The solution is the following:
const geojson = {
"name": "interseccao_circulo",
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
},
"geometry": {
"type": "MultiPoint",
"coordinates": [
[
-46.62831244066412,
-23.551014464955063
]
]
}
},
{
"type": "Feature",
"properties": {
},
"geometry": {
"type": "MultiPoint",
"coordinates": [
[
-46.63242614612176,
-23.55277865770234
]
]
}
}
]
}
var mymap = L.map('mapdiv', {
center:[-23.552778, -46.632426],
zoom:16,
maxZoom:20,
zoomControl:false,
attributionControl:false
});
var lyrOSRHOT = L.tileLayer.provider('OpenStreetMap.HOT');
mymap.addLayer(lyrOSRHOT);
L.geoJSON(geojson, {
pointToLayer: function (feature, latlng) {
const icons = new L.Icon({
iconUrl: "https://i.imgur.com/ZcGeIVz.png",
iconSize: [40, 40],
});
return L.marker(latlng, {icon: icons});
}
}).addTo(mymap);
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet-src.min.js" integrity="sha512-XQr+/1RXvYozXiwrumwtu3lqQmVwZ8nkLUrC/mc3HBHw4Imh++RXjwtLQFuOz3i65j9CSfKt50x6w/uUY2ovOQ==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-providers/1.12.0/leaflet-providers.min.js" integrity="sha512-LixflAm9c0/qONbz9F1Ept+QJ6QBpb7wUlPuyv1EHloTVgwSK8j3yMV3elnElGQcv7Y5QTFlF/FqyeE/N4LnKQ==" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet.css" integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==" crossorigin="anonymous" />
<div id="mapdiv" style="height:100vh; width: 100vw"></div>
Hi I want to generate a heatmap from a .geojson file with this plugin
How can I manage that? I'm very new to json, leaflet and web development.
The geoJSON file I have looks something like this (with more points ofc):
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"name": "testmarker",
"description": "This is a test description"
},
"geometry": {
"type": "Point",
"coordinates": [
-33.134766,
-60.326948
]
}
},
{
"type": "Feature",
"properties": {
"name": "testmarker2"
},
"geometry": {
"type": "Point",
"coordinates": [
-41.220703,
-62.552857
]
}
}
]
}
And here is what my index.html looks like right now.
<!DOCTYPE html>
<html = style="height: 100%;">
<head>
<title>Test Map</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="scripts/leaflet.css">
<script src="scripts/leaflet.js"></script>
<script src="scripts/leaflet.ajax.min.js"></script>
<script src="scripts/leaflet-heat.js"></script>
</head>
<body style="height: 100%;margin: 0;">
<div id="map" style="width: 100%; height: 100%; background: #000000;"></div>
<!-- Workaround for 1px lines appearing in some browsers due to fractional transforms
and resulting anti-aliasing.-->
<style>
.leaflet-tile-container img {
width: 256.5px !important;
height: 256.5px !important;
}
</style>
<script type="text/javascript">
// Creating the Map
var map = L.map('map').setView([58.602611, 50.350342], 4);
L.tileLayer('maps/mymap/{z}/{x}/{y}.png', {
continuousWorld: false,
noWrap: true,
minZoom: 2,
maxZoom: 6,
zoomControl: false,
minNativeZoom: 2,
maxNativeZoom: 6,
updateInterval: 200,
}).addTo(map);
// Remove old zoomControl and add new one in order to move it to bottomright
map.zoomControl.remove();
L.control.zoom({
position: 'bottomright'
}).addTo(map);
// Binds tooltip on all markers and also a popup on click if the markers has a description
function oef(feature, layer) {
if (feature.properties && feature.properties.name) {
layer.bindTooltip(feature.properties.name);
}
if (feature.properties && feature.properties.name && feature.properties.description) {
layer.bindPopup("<center><b> " + feature.properties.name + "</center></b><br>" + feature.properties.description);
}
}
var geojsonMarkers = new L.GeoJSON.AJAX(["https://raw.githubusercontent.com/***/test.geojson"],{onEachFeature:oef});
var mapOverlays={
"Test" : geojsonMarkers,
//"Test - Heat Map" : geojsonMarkersHeat,
}
var layerControl = L.control.layers(null, mapOverlays, {position:'topleft'}).addTo(map);
</script>
</body>
</html>
As you can see from above I want the heatmap to be toggleable via the mapOverlays but I don't really know how to proceed.
I have started playing around with Mapbox, and things are working as I would like, except that I have not been able to figure out how to disable clustering. Here is my code:
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title>Add custom icons with Markers</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v1.0.0/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v1.0.0/mapbox-gl.css' rel='stylesheet' />
<style>
body { margin:0; padding:0; }
#map { position:absolute; top:0; bottom:0; width:100%; }
</style>
</head>
<body>
<style>
.marker {
/*display: block;*/
border: none;
/*border-radius: 50%;*/
cursor: pointer;
padding: 0;
background-image: url('https://upload.wikimedia.org/wikipedia/commons/thumb/e/ed/Map_pin_icon.svg/176px-Map_pin_icon.svg.png');
background-size: cover;
width: 20px;
height: 27px;
/*border-radius: 50%;*/
/*cursor: pointer;*/
}
</style>
<div id='map'></div>
<script>
mapboxgl.accessToken = 'pk.eyJ1IjoibmFiZWxla3QiLCJhIjoiY2p4ZXVubnQwMGVmcTN6cGU0c3JpZmM2diJ9.peecDCcSljWhChxCknv7AQ';
var coordinates = [
[6.73579, 78.72300],
[2.70886, 11.51694],
[34.05482, -57.09742],
[-39.05019, 89.79126],
[17.44893, 35.57014],
[23.60105, 168.12674],
[-4.87631, 72.99334],
[39.7392, -104.9903],
[39.79905,-105.78118],
[39.80266,-105.78692],
[39.79758,-105.78061],
[39.80314,-105.78978],
[39.80313,-105.78999],
[39.80103,-105.78272],
[39.80096,-105.78259],
[39.80187,-105.78407],
[39.80283,-105.78593],
[39.79937,-105.78134],
[39.80023,-105.78164],
[39.80272,-105.78765],
[39.80263,-105.78673],
[39.80264,-105.78676],
[39.80125,-105.78326],
[39.7976,-105.78028],
[39.80316,-105.7905],
]
var num_coordinates = Object.keys(coordinates).length
var geojson = {
"type": "FeatureCollection",
"features": []
}
for (var coord_ind = 0; coord_ind < num_coordinates; coord_ind++) {
geojson.features.push({
"type": "Feature",
"properties": {
"message": "Bar",
"iconSize": [300, 300]
},
"geometry": {
"type": "Point",
"coordinates": [coordinates[coord_ind][1], coordinates[coord_ind][0]] // Longitude then Latitude
}
})
}
var map = new mapboxgl.Map({
container: 'map', // container id
style: 'mapbox://styles/mapbox/streets-v11', // stylesheet location
// style: 'mapbox://styles/mapbox/satellite-v9', // stylesheet location
center: [-99.66, 38.46], // starting position [lng, lat]
zoom: 5.5 // starting zoom
});
map.on('load', function() {
map.loadImage('https://upload.wikimedia.org/wikipedia/commons/thumb/e/ed/Map_pin_icon.svg/176px-Map_pin_icon.svg.png', function(error, image) {
if (error) throw error;
map.addImage('pin', image);
map.addSource("photo_locations", {
type: "geojson",
data: geojson,
cluster: false,
clusterMaxZoom: 1, // Max zoom to cluster points on
clusterRadius: 1 // Radius of each cluster when clustering points (defaults to 50)
});
map.addLayer({
"id": "points",
"type": "symbol",
"source": "photo_locations",
"layout": {
"icon-image": "pin",
"icon-size": 0.12
}
});
});
});
</script>
</body>
</html>
You can see that I have cluster: false set for my source. However, if you display this in your browser, the pins are still clustered together. If you zoom in on the pin to the west of Denver, you will see it separate into multiple pins.
How can I get clustering to disable entirely so that each individual pin can be seen at any zoom level? Any thoughts are appreciated. Thanks!
As geografa suggested, adding "icon-allow-overlap": true does the trick. This needs to be added to the layout section of the layer. So I now have:
...
"layout": {
"icon-image": "pin",
"icon-size": 0.08,
"icon-allow-overlap": true
}
...
var feature = {
"type": "feature",
"properties": {
"style": {
"color": "#004070",
"weight": 4,
"opacity": 1
}
},
"geometry": {
"type": "MultiPoint",
"coordinates": [[
[0.25, 51.47],
[0.26, 51.47],
[0.27, 51.47]
]]
}
};
var geojsonLayer = new L.GeoJSON(feature);
map.addLayer(geojsonLayer);
I am trying to show the above three points on my map. Why are the markers not appearing?
Make sure your GeoJSON data is compliant as per the spec. You have online linting tools available, e.g. http://geojsonlint.com/ and http://geojson.io/
In your case:
"Feature" type must be capitalized.
"coordinates" for a "MultiPoint" geometry type must be an array of positions / coordinates. But you have an array of array of coordinates. (one extra level)
Once these 2 mistakes are corrected, everything works:
var map = L.map('map');
var feature = {
"type": "Feature",
"properties": {
"style": {
"color": "#004070",
"weight": 4,
"opacity": 1
}
},
"geometry": {
"type": "MultiPoint",
"coordinates": [
[0.25, 51.47],
[0.26, 51.47],
[0.27, 51.47]
]
}
};
var geojsonLayer = new L.GeoJSON(feature);
map.addLayer(geojsonLayer).fitBounds(geojsonLayer.getBounds());
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="" />
<script src="https://unpkg.com/leaflet#1.3.1/dist/leaflet-src.js" integrity="sha512-IkGU/uDhB9u9F8k+2OsA6XXoowIhOuQL1NTgNZHY1nkURnqEGlDZq3GsfmdJdKFe1k1zOc6YU2K7qY+hF9AodA==" crossorigin=""></script>
<div id="map" style="height: 180px"></div>
I am trying to use the following code to highlight features under the mouse pointer.
The difference between my geojson data and the geojson data used in the linked example is that the example is made up of polygons whereas my geojson is made up of polylines. I have tried to modify the code accordingly in order that lines are highlighted however it does not work.
My geojson is accessible here:
http://iskandarblue.github.io/mapbox/data/prototype2.geojson
Any advice on what needs to be changed?
Example:
https://www.mapbox.com/mapbox-gl-js/example/hover-styles/
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>HTML markers from geoJSON url</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.15.0/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.15.0/mapbox-gl.css' rel='stylesheet'/>
<style>
body { margin:0; padding:0; }
#map { position:absolute; top:0; bottom:0; width:100%; }
</style>
</head>
<body>
<div id='map'></div>
<script>
mapboxgl.accessToken = 'pk.eyJ1IjoiaXNrYW5kYXJibHVlIiwiYSI6ImNpbHIxMXA3ejAwNWl2Zmx5aXl2MzRhbG4ifQ.qsQjbbm1A71QzVg8OcR7rQ';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v8',
center: [37.625224, 55.744537,],
zoom: 13
});
map.on('style.load', function () {
map.addSource("streets", {
"type": "geojson",
"data": "http://iskandarblue.github.io/mapbox/data/prototype2.geojson"
});
map.addLayer({
"id": "m_streets",
"type": "line",
"source": "streets",
"interactive": true,
"layout": {},
"paint": {
"line-color": "#627BC1",
"line-width": 2.5
}
});
map.addLayer({
"id": "route-hover",
"type": "line",
"source": "streets",
"layout": {},
"paint": {
"line-color": "#627BC1",
"line-width": 2.5
},
"filter": ["==", "rd_name", ""]
});
// When the user moves their mouse over the page, we look for features
// at the mouse position (e.point) and within the states layer (states-fill).
// If a feature is found, then we'll update the filter in the route-hover
// layer to only show that state, thus making a hover effect.
map.on("mousemove", function(e) {
map.featuresAt(e.point, {
radius: 5,
layer: ["m_streets"]
}, function (err, features) {
if (!err && features.length) {
map.setFilter("route-hover", ["==", "rd_name", features[0].properties.rd_name]);
} else {
map.setFilter("route-hover", ["==", "rd_name", ""]);
}
});
});
});
//.addTo(map);
</script>
</body>
</html>
The route-hover layer just needs to be styled differently right? Here's a live example of your code above with a slight adjustment: https://jsbin.com/loxoquwiye/