Javascript Function & Variable Scope using geolocation - javascript

I'm trying to use geolocation to get my current position, which inserts the lat and lon into the centre point of a map. I know that geolocation is asynchronous, so I have to get that value, then call another function for this to pass forward. I am not getting the object mymap created for some reason.
<script>
function foundLocation(pos) {
setMyLocation(pos.coords.latitude, pos.coords.longitude)
};
function noLocation() {
document.getElementById("warning").innerHTML = "Could not find your location";
};
function setMyLocation(myLat, myLon) {
L.marker([ myLat, myLon ], {icon: homeIcon}).bindPopup("You Are Here").addTo(coolPlaces);
var mymap = L.map('mapid', {
center: [ myLat, myLon ],
minZoom: 2,
maxZoom: 18,
zoom: 15,
layers: [mymarkers]
});
};
navigator.geolocation.getCurrentPosition(foundLocation, noLocation);
<snip other JS irrelevant stuff>
</script>
Is there a way I can get those two variables out of the function and create the mymap object? I'm not well versed in JS and its restrictions.
The above code results in no map generated. I have to take mymap outside the geolocation functions for this to happen. The issue is that I don't know how to send myLat and myLon outside to that declaration.

Kudos to #espascarello: All the map functionality inside the success function foundLocation(pos).
Update: The problem is above. Read it. Putting every map function inside foundLocation(pos) worked fine. There's no use for any map function if these two variables are not found.
myLat = 0
myLon = 0
mymap = ""
function foundLocation(pos) {
myLat = pos.coords.latitude;
myLon = pos.coords.longitude;
// setMyLocation(pos.coords.latitude, pos.coords.longitude)
var homeIcon = L.icon({
iconUrl: '/img/house_marker.png',
iconSize: [24, 24],
iconAnchor: [12, 24],
popupAnchor: [0, -24]
});
var mymarkers = L.layerGroup([
L.marker([ myLat, myLon ], {icon: homeIcon}).bindPopup("You Are Here"),
<%= #markers %>
]);
var mymap = L.map('mapid', {
center: [ myLat,myLon ],
minZoom: 2,
maxZoom: 18,
zoom: 15,
layers: [mymarkers]
});
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw', {
attribution: 'Map data © OpenStreetMap Imagery © Mapbox',
id: 'mapbox.streets'
}).addTo(mymap);
L.control.layers(mymarkers).addTo(mymap);
};
function noLocation() {
document.getElementById("warning").innerHTML = "Could not find your location";
};
function setMyLocation(pushLat, pushLon) {
alert("inside setMyLocation");
myLat = pushLat;
myLon = pushLon;
// var mymap = L.map('mapid', {
// center: [ myLat, myLon ],
// minZoom: 2,
// maxZoom: 18,
// zoom: 15,
// layers: [mymarkers]
// });
};
navigator.geolocation.getCurrentPosition(foundLocation, noLocation);

Related

Leaflet .on() Eventlistener with markers

So I have a js file to implement a leaflet map in my blade file.
$(document).ready(function(){
const container = document.getElementById('kkpAllMap')
if(container) {
var coordinates = $('#kkpAllMap').data('coordinates')
const kkpAllMap = L.map(
'kkpAllMap',
{
center: [11.5639911, 104.909288],
zoom: 13,
}
)
L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox',
maxZoom: 50,
id: 'mapbox/streets-v11',
tileSize: 512,
zoomOffset: -1,
accessToken: mytoken
}).addTo(kkpAllMap);
var kkpnIcon = L.icon({
iconUrl: '/icons/kkpIcon.png',
iconSize: [38, 65], // size of the icon
iconAnchor: [19, 64], // point of the icon which will correspond to marker's location
popupAnchor: [-5, -56] // point from which the popup should open relative to the iconAnchor
});
var markers = []
for (var i = 0; i < coordinates.length; i++) {
var marker = L.marker(
[coordinates[i][1], coordinates[i][2]],
{icon: kkpnIcon}
)
.addTo(kkpAllMap)
.on('click', {foo: "bar"}, clickZoom);
markers.push(marker)
}
function clickZoom(e) {
kkpAllMap.setView(e.target.getLatLng(),15);
console.log(e.data.foo)
}
}
})
when I click on each markers, i want to log the parameter (foo) that I passed to my function. Instead, it gave me this error:
leaflet.js:5 Uncaught TypeError: a.fn.call is not a function
Anyone knows how to solve this problem?
This works for me!
$(document).ready(function(){
const container = document.getElementById('kkpAllMap')
if(container) {
var coordinates = $('#kkpAllMap').data('coordinates')
const kkpAllMap = L.map(
'kkpAllMap',
{
center: [11.5639911, 104.909288],
zoom: 13,
}
)
L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox',
maxZoom: 50,
id: 'mapbox/streets-v11',
tileSize: 512,
zoomOffset: -1,
accessToken: mytoken
}).addTo(kkpAllMap);
var kkpnIcon = L.icon({
iconUrl: '/icons/kkpIcon.png',
iconSize: [38, 65], // size of the icon
iconAnchor: [19, 64], // point of the icon which will correspond to marker's location
popupAnchor: [-5, -56] // point from which the popup should open relative to the iconAnchor
});
var markers = []
for (var i = 0; i < coordinates.length; i++) {
var marker = L.marker(
[coordinates[i][1], coordinates[i][2]],
{icon: kkpnIcon}
)
.addTo(kkpAllMap)
.on('click', function(e){
clickZoom(e, {foo: 'bar'})
})
markers.push(marker)
}
function clickZoom(e, data) {
kkpAllMap.setView(e.target.getLatLng(),15);
console.log(data)
}
}
})
but i want to pass my partner_id, so I would do this instead.
$(document).ready(function(){
const container = document.getElementById('kkpAllMap')
if(container) {
var coordinates = $('#kkpAllMap').data('coordinates')
const kkpAllMap = L.map(
'kkpAllMap',
{
center: [11.5639911, 104.909288],
zoom: 13,
}
)
L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox',
maxZoom: 50,
id: 'mapbox/streets-v11',
tileSize: 512,
zoomOffset: -1,
accessToken: mytoken
}).addTo(kkpAllMap);
var kkpnIcon = L.icon({
iconUrl: '/icons/kkpIcon.png',
iconSize: [38, 65], // size of the icon
iconAnchor: [19, 64], // point of the icon which will correspond to marker's location
popupAnchor: [-5, -56] // point from which the popup should open relative to the iconAnchor
});
var markers = []
for (var i = 0; i < coordinates.length; i++) {
var marker = L.marker(
[coordinates[i][1], coordinates[i][2]],
{icon: kkpnIcon, partner_id: coordinates[i][0]}
)
.addTo(kkpAllMap)
.on('click', clickZoom)
markers.push(marker)
}
function clickZoom(e) {
kkpAllMap.setView(e.target.getLatLng(),15);
console.log(e.target.options.partner_id)
}
}
})

How to define locate control in Leaflet and Angular 2

I would like to define a locate control in my Leaflet Angular 2 project.
For now I have this code
ngOnInit() {
let map = L.map("map", {
center: [48.13, 11.57],
zoom: 13,
zoomControl: true,
maxZoom: 30,
minZoom: 8,
}).addLayer(this.googleStreets);
map.invalidateSize();
map.locate({setView: true, maxZoom: 16, watch: true});
L.control.scale().addTo(map);
function onLocationFound(e) {
var radius = e.accuracy/2;
L.circle(e.latlng, radius).addTo(map);
}
map.on('locationfound', onLocationFound);
}
The map searches location automatically and shows where user is.
I would like to add GPS icon thing to my map, like on the picture.
How could I implement this in Angular 2?
You can just use the location that you got from the locationFound() function and add a new marker with that latlngs.

Leaflet rendering one polygon in a list of polygons

I have a leaflet map with django. I'm passing geojson from a database. For some reason, I'm not getting any errors, but it's only rendering one polygon instead of around 3,000. Everything else seems to be working correctly.
It's technically not a multipolygon since there aren't shapes inside this shape but a bunch of shapes rendered in the same place.
function initmap(){
var map = new L.map('map',{
center: [1.0,1.0],
layers: [osmLayer,markers,parcelLayer],
minZoom: 1,
zoom: 3 }
).setView([lat,long],13 );
}
var osmLayer = new L.tileLayer( 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap',
subdomains: ['a','b','c']
});
var markers = new L.FeatureGroup();
var parcelFeature = ['{"geometry": {"type": "Polygon", "coordinates": [[[a,b],[c,d],[e,f],[g,h]]]}, "type": "Feature"}',
'{"geometry": {"type": "Polygon", "coordinates": [[[i,j],[k,l],[m,n],[o,p]]], "type": "Feature"}'];
parcelFeature = JSON.parse(parcelFeature[0]);
var parcelLayer = L.geoJson([parcelFeature],{
style : {
"color": "#000000",
"weight": 3,
"opacity": 10.65
}
});
parcelLayer.on("loaded", function(e) {map.fitBounds(e.target.getBounds());} );
//marker icon
var ceIcon = L.icon({
iconUrl: "/static/maps/leaflet/images/somepng.png",
iconSize: [45,45],
iconAnchor: [0, 0],
popupAnchor: [-3, -76]
});
//add markers
marker = new L.marker([lat,long], {icon:ceIcon});
markers.addLayer(marker);
marker = new L.marker([lat,long], {icon:ceIcon});
markers.addLayer(marker);
marker = new L.marker([lat,long], {icon:ceIcon});
markers.addLayer(marker);
marker = new L.marker([lat,long], {icon:ceIcon});
markers.addLayer(marker);
initmap();
What I did was pass this through django as a json and then splitting in javascript each json item and adding it to a new list.
var parcelFeature = [];
var parcel_json = {{ parcel_json|safe }};
for(i = 0; i < parcel_json.length; i++){
var pjson = parcel_json[i];
pjson = JSON.parse(pjson);
parcelFeature.push(pjson);
}
After this I used the default L.geoJson layer and it rendered correctly. Not sure the issue.
var parcelLayer = L.geoJson(parcelFeature,
{ style :{
"color": "#000000",
"weight": 1,
"opacity": 100},
"fillColor":"#FFFFFF",
onEachFeature: function(feature, layer) {
// does this feature have a property named popupContent?
if (feature.properties && feature.properties.popupContent) {
layer.bindPopup(feature.properties.popupContent);
console.dir(feature.properties.popupContent);
} }
});

Google maps is not working on live but working in local

Html Code
<div class="panel-body">
<div id="map_canvas" style="position: relative;width: 1050px;top: 100%;bottom: 0;height: 500px;"></div>
</div>
Jquery
https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js
https://maps.googleapis.com/maps/api/js?key=**********&callback=initMap
function initMap() {
var map = new google.maps.Map(document.getElementById('map_canvas'), {
zoom: 4,
center: {lat: 20.5937, lng: 78.9629}
});
setMarkers(map);
}
var beaches = [
['India', 20.5937, 78.9629, 1],
];
function setMarkers(map) {
var image = {
url: 'https://developers.google.com/maps/documentation/javascript/examples/full/images/beachflag.png',
size: new google.maps.Size(20, 32),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(0, 32)
};
var shape = {
coords: [1, 1, 1, 20, 18, 20, 18, 1],
type: 'poly'
};
for (var i = 0; i < beaches.length; i++) {
var beach = beaches[i];
console.log(beach);
var marker = new google.maps.Marker({
position: {lat: beach[1], lng: beach[2]},
map: map,
icon: image,
shape: shape,
title: beach[0],
zIndex: beach[3]
});
}
}
here is the code of the google maps.
The problem is in the production but it is working fine in local.
The error is as follows for production :
Uncaught TypeError: Cannot read property 'firstChild' of null
at Object._.vg (js?key=AIzaSyDSGjhKsJgMAQmzn1E5UTGQvKtNLKKqMNo&callback=initMap:90)
at new Ag (js?key=AIzaSyDSGjhKsJgMAQmzn1E5UTGQvKtNLKKqMNo&callback=initMap:92)
at initMap (location:222)
at js?key=AIzaSyDSGjhKsJgMAQmzn1E5UTGQvKtNLKKqMNo&callback=initMap:98
at js?key=AIzaSyDSGjhKsJgMAQmzn1E5UTGQvKtNLKKqMNo&callback=initMap:56
at Object._.Mc (js?key=AIzaSyDSGjhKsJgMAQmzn1E5UTGQvKtNLKKqMNo&callback=initMap:53)
at Xc (js?key=AIzaSyDSGjhKsJgMAQmzn1E5UTGQvKtNLKKqMNo&callback=initMap:56)
at js?key=AIzaSyDSGjhKsJgMAQmzn1E5UTGQvKtNLKKqMNo&callback=initMap:135
at Object.google.maps.Load (js?key=AIzaSyDSGjhKsJgMAQmzn1E5UTGQvKtNLKKqMNo&callback=initMap:21)
at js?key=AIzaSyDSGjhKsJgMAQmzn1E5UTGQvKtNLKKqMNo&callback=initMap:134

Leaflet shows only part of the markers

I'm using Leaflet, leaflet.geo.csv and leaflet-sidebar to build a map. Map works and shows me markers but only 25 of 200. Not the 25 first but randomly among the 200. And it is always the same ones that appear.
I can't show you my csv (sensitive data) but I have checked it many times, clean it and I think it is fine. My console is empty.
This is a sample of my code :
var map = L.map('map');
var affaires = L.geoCsv(null, {
onEachFeature: function (feature, layer) {
var popup = '';
for (var key in feature.properties) {
var title = affaires.getPropertyTitle(key);
popup += '<p class="title">'+title+'</b><p class="info">'+feature.properties[key]+'</p>';
}
layer.on('click', function () {
sidebar.hide();
sidebar.show();
sidebar.setContent(popup);
});
},
pointToLayer: function (feature, latlng) {
return L.marker(latlng, {
icon:L.icon({
iconUrl: 'marker.png',
shadowUrl: 'shadow.png',
iconSize: [25,38],
shadowSize: [41, 41],
shadowAnchor: [13, 21]
})
});
},
firstLineTitles: true,
fieldSeparator: ','
});
$.ajax ({
type:'GET',
dataType:'text',
url:'mydata.csv',
error: function() {
alert('Pas de données');
},
success: function(csv) {
var markers = new L.Marker();
affaires.addData(csv);
map.addLayer(affaires);
map.fitBounds(affaires.getBounds());
console.log(affaires);
}
});
L.tileLayer('http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap © CartoDB | © lamontagne.fr - Julien Jégo',
subdomains: 'abcd',
maxZoom: 19
}).addTo(map);
var sidebar = L.control.sidebar('sidebar', {
closeButton: true,
position: 'left'
});
map.addControl(sidebar); ...
A screenshot of my map :
Any suggestion ?
Thanks

Categories

Resources