I'm trying to figure out how to pass in coordinates to the L.LatLng function in leaflet so that it can map the coordinates.
I can successfully load in the data, and it looks like this:
//This is the structure of the geojson data, as an example
var SanFranciscoData = {"type":"FeatureCollection", "features": [
{"type":"Feature","geometry":{"type":"Point","coordinates":[-96.97593699999999,32.889954000000046]}
//Load in the geojson
d3.json("data/dataPoints.json", function(SFData) {
var SFData = SanFranciscoData.features
})
//pass in coordinates to the L.LatLng leaflet function
SFData.forEach(function(d) {
d.latLong = new L.LatLng(d.features.geometry.coordinates[1],
d.features.geometry.coordinates[0]);
})
I've also tried, as I've seen done in examples:
var coords = SFData.feature.geometry.coordinates;
Both methods above give the same result: the coordinates are undefined. What am I doing wrong? I'm not sure how to access the coordinates array using object notation in order to access the lat / longs.
Ok.. this worked:
SFData.forEach(function(d) {
var coords = d.geometry.coordinates
console.log(coords)
d.latLong = new L.LatLng(coords[1],
coords[0]);
})
Seems as if coordinates needed to be defined withing the .forEach function!
Related
I know this is a common error but I'm not seeing my specific problem. Doing a little basic JS practice and running into this error only when using a nested array of coordinate pairs. If I only try and map one single location the error goes away. Any thoughts as to why this might be happening? Code below.
var options = {
center: [39.8333,-98.5833],
zoom: 4
}
// instantiate the leaflet object
var map = L.map('map', options);
// Get basemap URL from Leaflet Providers
var basemap_url = 'http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}'
// Get basemap attributes from Leaflet Providers
var basemap_attributes = {
attribution: 'Tiles © Esri — Source: Esri, DeLorme, NAVTEQ, USGS, Intermap, iPC, NRCAN, Esri Japan, METI, Esri China (Hong Kong), Esri (Thailand), TomTom, 2012'
}
// Add tileset as a layer in our map by passing as arguments to tileLayer method
var tiles = L.tileLayer(basemap_url, basemap_attributes);
// add tiles to map with addLayer method
map.addLayer(tiles);
// variable to hold string value of cities
var cities = ["Victoria", "Bettles", "Truth or Consequences"];
var cityCoords = [
[48.430077, -123.353043],
[66.905857, -151.533330],
[33.1284, -107.25283]
];
var cityPops = [92141, 13, 5948];
var cityCapitals = [true, false, false];
// loop through all the elements in the cities array
for(let i = 0; i <= cities.length; i++){
let cityName = cities[i];
let cityPop = cityPops[i];
let cityCap = cityCapitals[i];
let namePop = `<b>${cityName}</b><br> population: <b>${cityPop}</b><br>`;
let popup = `${cityName} population: ${cityPop}`
console.log(popup)
if (cityCap == true) {
popup += 'is a capital city'}
L.marker(cityCoords).addTo(map)
.bindPopup(popup);
}
As commented, replacing
L.marker(cityCoords).addTo(map)
with
L.marker(cityCoords[i]).addTo(map)
solves the problem by passing a LatLng array of numbers to marker as covered in documentation.
I deduce that Leaflet converts an array of arrays to null if the array should have contained numeric coordinate values, and then generates errors trying to access lat or lng properties of what should have been a valid conversion result.
I am trying to draw an arrowhead for each point in a kml file. For this I plan to fetch coordinates for each point by getById. So far I am getting an error:
Uncaught TypeError: Cannot read property 'position' of undefined (on line 14)
Here is my code:
var src = Cesium.KmlDataSource.load('../../My_KML/plots.kml', options);
viewer.dataSources.add(src).then(function(data) {viewer.flyTo(data);});
//-------------------********--------------**********-----------------//
var point = viewer.entities.getById('geom_20102');
var entities = viewer.entities;
var cartographicPosition = Cesium.Cartographic.fromCartesian(point.position.getValue(Cesium.JulianDate.now()));
var latitude = Cesium.Math.toDegrees(cartographicPosition.latitude);
var longitude = Cesium.Math.toDegrees(cartographicPosition.longitude);
var line1 = entities.add({
polyline : {
positions : Cesium.Cartesian3.fromDegreesArrayHeights([longitude, latitude, 360, longitude + 1, latitude + 1, 400]),
width : 10,
followSurface : false,
material : new Cesium.PolylineArrowMaterialProperty(Cesium.Color.BLUE)
}
});
I have specified the element with id 'geom_20102' as a linestring wrapped around by a placemark in the kml. Also I would like to know which id to specify as both placemark and linestring have an id. Or am I confusing kml id with entity id?
I am new to Cesium.Js and I followed this example partially:
Cesium Workshop
KML snippet:
<Placemark id="feat_20125">
<name>874</name>
<styleUrl>#stylesel_20102</styleUrl>
<LineString id="geom_20102">
<coordinates>104.99108,10.4118,247.3 72.991075,26.25412,247.6</coordinates>
<altitudeMode>relativeToGround</altitudeMode>
</LineString>
</Placemark>
Two things are going on here.
First, the Cesium.KmlDataSource.load() function returns a JavaScript "Promise" which represents the eventual completion (or failure) of an asynchronous operation. At the time the viewer.entities is referenced in the code, the KML file has not yet loaded so the collection in viewer.entities is empty and calling getById() on it will return undefined. You should only access the viewer.entities or data.entities after the async Promise is completed and the "then" callback is invoked. Only at that time are the entities populated.
var src = Cesium.KmlDataSource.load('../../My_KML/plots.kml', options);
viewer.dataSources.add(src).then(function(data) {
var entities = data.entities;
console.log("f=" + entities.getById('feat_20125')); // f=[object Object]
console.log("g=" + entities.getById('geom_20102')); // undefined
viewer.flyTo(data);
});
Next, notice that the 'feat_20125' returns an object but the 'geom_20102' is not found. Only the "id" on the placemarks are populated when KML is converted into Cesium entities. Ids on any other KML element are discarded.
How do I know the name or id of the marker that is clicked?
And is it possible?
Is there a way to find the label/name of the marker like this for example:
onMarkerClick: function(label){
alert(label.text());
}
All help appreciated :)
The second parameter in the click handler function is the key/index of the marker object.
onMarkerClick (Event e, String code)
One possible way to do that, is:
onMarkerClick: function(e, code) {
var mapObj = $("#map").vectorMap("get", "mapObject");
var idx = parseInt(code); // optional
var name = mapObj.markers[idx].config.name;
var latitude = mapObj.markers[idx].config.latLng[0];
var longitude = mapObj.markers[idx].config.latLng[1];
}
Explanation:
depending how you created the markers, you may need to get the index
as numeric value
by default, each marker is storing the name and the coords of the point
If you need more info, try to explore the properties of the map object in the browser, like this: console.log(mapObj.markers);
I am passing an array of objects to my jade template, and want to use it as var in my js.
it seems to be transferred correctly, as
each level, i in stats
.levelStats
creates 4 divs (as expected)
now i have
script(type='text/javascript').
var statData = "!{stats}"
which, as far as i know, should load the data into a javascript var.
it does that, in a way...
console.log(statData);
// output: [object Object],[object Object],[object Object],[object Object]
// this means the correct data must be there..somewhere
console.log(typeof statData);
// output: string
what am I doing wrong?
how can i get the whole array into the var?
solution + lesson:
var foo = "!{bar}" makes the data a string (pretty obvious in restrospective)
right way to go: var foo = !{bar}
each level, i in stats
.levelStats
You are looping over (an array ?) stats where i is an index and level the element of your array at stats[i].
but you don't seem to use the elements separatly :
var statData = "!{stats}"
stats still the array, you will find each element in level !
Edit :
After clarification, to keep the whole array and set it to a variable :
var statData = !{JSON.stringify(stats)}
You need to put a string in the <script> tag. How to make array into a string, so that you can convert it back later? JSON.stringify.
So, something like this should work:
script.
var statData = !{JSON.stringify(stats)};
I spent full day to make it work. It is more advanced example, but we pass array to js in jade/pug file. Here we pass array of locations to google maps init script. Use it like this:
1)Prepare data on the server
JSON.stringify(locations = [
{ lat: -31.563910, lng: 147.154312 },
{ lat: -33.718234, lng: 150.363181 },
{ lat: 52.319277, lng: 21.000466 }
])
2)pass it to your pug/jade page.
There, use this with variable that you pass, for example: DATA_THAT_YOUPASS
script.
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 3,
center: {lat: 52.5191758, lng: 23.0002262}
});
// Create an array of alphabetical characters used to label the markers.
var labels = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
// Add some markers to the map.
// Note: The code uses the JavaScript Array.prototype.map() method to
// create an array of markers based on a given "locations" array.
// The map() method here has nothing to do with the Google Maps API.
var markers = locations.map(function(location, i) {
return new google.maps.Marker({
position: location,
label: labels[i % labels.length]
});
});
// Add a marker clusterer to manage the markers.
var markerCluster = new MarkerClusterer(map, markers,
{imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'});
}
var mydata = !{DATA_THAT_YOUPASS}
console.log(mydata);
console.log(mydata);
var locations = mydata;
#map
script(src='https://unpkg.com/#google/markerclustererplus#4.0.1/dist/markerclustererplus.min.js')
// Replace the value of the key parameter with your own API key.
script(async='', defer='', src='https://maps.googleapis.com/maps/api/js?key=XXXXXXXXXXXXXXXXXXXXXXXXXX&callback=initMap')
Hi there I am Using appcelerator, and I want to integrate a map with an array of markers I am getting from a HTTPRequest...
I am effing lost, totally lost.
This is how the map looks like:
var mapview = Titanium.Map.createView({
mapType: Titanium.Map.STANDARD_TYPE,
region: {latitude:33.74511, longitude:-84.38993,
latitudeDelta:0.01, longitudeDelta:0.01},
animate:true,
regionFit:true,
userLocation:true,
annotations:[mountainView]
});
And I have the example of 1 marker hardcoded ...
var mountainView = Titanium.Map.createAnnotation({
latitude:37.390749,
longitude:-122.081651,
title:"Appcelerator Headquarters",
subtitle:'Mountain View, CA',
pincolor:Titanium.Map.ANNOTATION_RED,
animate:true,
leftButton: '../images/appcelerator_small.png',
myid:1 // CUSTOM ATTRIBUTE THAT IS PASSED INTO EVENT OBJECTS
});
So yo create the marker and in the annotations section you add it to the map, the thing here is that I am getting the markers from this:
var url = "http://myURLwithMyParameters";
var xhr = Ti.Network.createHTTPClient({
onload: function(e) {
// this function is called when data is returned from the server and available for use
// this.responseText holds the raw text return of the message (used for text/JSON)
var result = this.responseText;
var xml = Ti.XML.parseString(result);
var items = xml.documentElement.getElementsByTagName("marker");
var name = xml.documentElement.getElementsByTagName("name");
var value = xml.documentElement.getElementsByTagName("address");
var data = [];
for (var i=0;i<items.length;i++) {
data.push({
name: items.item[i].getElementsByTagName("name")[0].textContent,
address: items.item[i].getElementsByTagName("address")[0].textContent
})
Does any one know how to integrate this?
I think I must build the map in the same function as the markers, but I've tried several options and haven't found ANY example of this in the web.
Any clue would be very appreciated.
Thank you in advance.
If all you have is an address, you'll need to forward geocode those addresses to get lat/long coordinates. Those coords are required to place annotations on the map. Check the docs at forwardGeocoder(). There's an example in the KitchenSink