I'm using this code to draw a point on a map:
function addPointToMap(pMap){
var coordinates = new Array();
// Style Point
var style_blue = OpenLayers.Util.extend({}, OpenLayers.Feature.Vector.style['default']);
style_blue.strokeColor = "blue";
style_blue.fillColor = "blue";
// Make Point
coordinates.push(new OpenLayers.Geometry.Point(33, 33));
var pointFeature = new OpenLayers.Feature.Vector(coordinates, null, style_blue);
// Layer
var pointsLayer = new OpenLayers.Layer.Vector("Points Layer");
pointsLayer.addFeatures([pointFeature]);
pMap.addLayer(pointsLayer);
}
I'm getting this error from the console:
Uncaught TypeError: Object POINT(33, 33) has no method 'getBounds'
What am I doing wrong?
For the sake of completeness, I received a similar error while adding a polygon (not a point) from raw WKT data. The error that there are no bounds occur because the object was of the wrong type.
When you call addFeatures, it expects an array of OpenLayers.Feature.Vector objects, which are created by Format.read.
var wkt_parser = new OpenLayers.Format.WKT();
var wkt_data_parsed = wkt_parser.read(some_raw_wkt_data_string);
layer.addFeatures([wkt_data_parsed]);
The answer is to add a multipoint geometry:
function addPointToMap(pMap){
var coordinates = new Array();
// Style Point
var style_blue = OpenLayers.Util.extend({}, OpenLayers.Feature.Vector.style['default']);
style_blue.strokeColor = "blue";
style_blue.fillColor = "blue";
// Make Point
coordinates.push(new OpenLayers.Geometry.Point(lon, lat));
var pointsGeometry = new OpenLayers.Geometry.MultiPoint(coordinates);
var pointFeature = new OpenLayers.Feature.Vector(pointsGeometry, null, style_blue);
// Layer
var pointsLayer = new OpenLayers.Layer.Vector("Points Layer");
pointsLayer.addFeatures([pointFeature]);
pMap.addLayer(pointsLayer);
}
Does your map have a 'baselayer'? Otherwise you should add option 'alloverlays'=true to your map options. I'm not sure if this solves your problem though...
Related
I have fixed an issue with the drawing circles by the Leaflet draw plugin, where the Turf library has been provided.
Everything works fine, apart from the data, which I passed earlier by the prompt function. They come out only in the point created as the circle by standard code. Unfortunately, it is nothing for TurfCircle the same as NewTurfBuffer.
My code (used in Python folium) looks as follows:
map.on(L.Draw.Event.CREATED, function(e) {
var layer = e.layer,
type = e.layerType;
feature = layer.feature = layer.feature || {}; // Initialize feature
let x = 1
var title = prompt("Please provide the name", "default");
var value = prompt("Please provide the value", "undefined");
var id = x++;
feature.type = feature.type || "Feature"; // Initialize feature type
if (type === 'circle') {
var theCenterPt = layer.getLatLng();
var center = [theCenterPt.lng,theCenterPt.lat];
console.log(center);
console.log(title);
var theRadius = layer.getRadius();
var turfCircle;
var options = {steps: 256, units: 'meters'};
var turfCirle = turf.circle(center, theRadius, options);
var NewTurfCircle = new L.GeoJSON(turfCircle)
drawnItems.addLayer(NewTurfCircle);
var thepoint = turf.point(center);
var buffered = turf.buffer(thepoint, theRadius, {units: 'meters'});
var NewTurfBuffer = new L.GeoJSON(buffered)
drawnItems.addLayer(NewTurfBuffer);
}
var props = feature.properties = feature.properties || {}; // Initialize feature properties
props.Id = id;
props.Title = title;
props.Value = value;
var coords = JSON.stringify(layer.toGeoJSON(), NewTurfBuffer);
{%- if this.show_geometry_on_click %}
layer.on('click', function() {
alert(coords);
console.log(coords);
});
{%- endif %}
drawnItems.addLayer(layer);
});
I still get empty properties for my FeatureCollection
I think the issue can be similar to this one:
Why doesn't JSON.stringify display object properties that are functions?
https://gis.stackexchange.com/questions/332908/overlay-with-the-feature-collection-properties
but it looks like I am wrong in placing my properties inside of the FeatureCollection
https://gis.stackexchange.com/questions/25279/is-it-valid-to-have-a-properties-element-in-an-geojson-featurecollection
anyway, I am looking for a solution that will allow me to pass the data to these properties boxes.
UPDATE II:
I tried
var buffered = turf.buffer(thepoint, theRadius, {units: 'meters'});
buffered.push(layer.feature);
var NewTurfBuffer = new L.GeoJSON(buffered)
drawnItems.addLayer(NewTurfBuffer);
but an error occurs:
buffered.push is not a function
Hint taken from here:
https://gis.stackexchange.com/questions/285352/how-to-get-the-exact-circle-that-user-has-drawn-using-leaflet-draw-circle
I have a JSON with different points. Each point has a different fields, like lon1 , lat1, lon2, lat2.
For each point I draw a line from point 1 to point 2.
By means of a for I perform this operation for each point and I draw different polylines in the map.
The problem is that when I activate or deactivate the layer, only the last drawn line is hidden, not all lines.
In the map you can see all the lines, but it seems that in the layer it overwrites and deletes the last line generated.
Code:
for (var i = 0; i < json_ARAPointsPRU_0.features.length; i++) {
var Lon1 = json_ARAPointsPRU_0.features[i].properties['Lon(d.dd)'];
var Lat1 = json_ARAPointsPRU_0.features[i].properties['Lat(d.dd)'];
var Lon2 = json_ARAPointsPRU_0.features[i].properties['LON2'];
var Lat2 = json_ARAPointsPRU_0.features[i].properties['LAT2'];
// array of coordinates
var mylatlngs = [
[Lat1, Lon1],
[Lat2, Lon2]
];
// draw a polyline in the map
var polilineas = L.polyline(mylatlngs, {
color: 'blue'
});
polilineas.addTo(map);
// add " polilineas" into other layer
var Velocidad2D = new L.LayerGroup();
Velocidad2D.addLayer(polilineas);
// Velocidad2D.addLayer(cabezas); Possibility to add arrow head
}
// Code to LAYER CONTROL
var gropedOverlayslehen = {
"Vel 2D": Velocidad2D
}
var layerControl = L.control.layers(basemaps, gropedOverlayslehen);
layerControl.addTo(map);
You need to put var Velocidad2D = new L.LayerGroup(); to the outside of the loop, else you overwrite it everytime.
var Velocidad2D = new L.LayerGroup();
for (var i = 0; i < json_ARAPointsPRU_0.features.length; i++) {
var Lon1 = json_ARAPointsPRU_0.features[i].properties['Lon(d.dd)'];
var Lat1 = json_ARAPointsPRU_0.features[i].properties['Lat(d.dd)'];
var Lon2 = json_ARAPointsPRU_0.features[i].properties['LON2'];
var Lat2 = json_ARAPointsPRU_0.features[i].properties['LAT2'];
// array of coordinates
var mylatlngs = [
[Lat1, Lon1],
[Lat2, Lon2]
];
// draw a polyline in the map
var polilineas = L.polyline(mylatlngs, {
color: 'blue'
});
polilineas.addTo(map);
// add " polilineas" into other layer
Velocidad2D.addLayer(polilineas);
// Velocidad2D.addLayer(cabezas); Possibility to add arrow head
}
// Code to LAYER CONTROL
var gropedOverlayslehen = {
"Vel 2D": Velocidad2D
}
var layerControl = L.control.layers(basemaps, gropedOverlayslehen);
layerControl.addTo(map);
I'm trying to fit a map to bounds defined by a 2D array. I keep getting the error Error: Bounds are not valid. leaflet.js:5:21909 even though the markers are added to the map and are valid coords.
var map = L.map('map', { zoomControl:false });
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map);
map.setView([0, 0], 2);
var markers = new L.FeatureGroup();
map.addLayer(markers);
function drawResults(){
// get offer keys
var offers = new Array();
var articles = [];
offersRef.once("value", function(snapshot) {
var offerKeys = Object.keys(snapshot.val());
for (var i=0; i<offerKeys.length; i++){
var offer = snapshot.val()[offerKeys[i]];
var lat = offer.lat;
var lng = offer.lng;
console.log(lat);// outputs 33.2321
console.log(lng);// outputs 101.1234
offers.push([lat, lng]);
var marker = L.marker([lat, lng]).addTo(markers);
}
});
map.fitBounds(markers.getBounds());
}
console.log(offers);
}
drawResults();
Can anyone see what I'm doing wrong?
Edit:
Console logs
35.0721909 app.js:350:13
-106.48798399999998 app.js:351:13
35.0526641 app.js:350:13
-78.87835849999999 app.js:351:13
You will need to move the call to map.fitBounds into the callback, as the once method (which looks like a Firebase API call) is likely asynchronous:
offersRef.once("value", function(snapshot) {
var offerKeys = Object.keys(snapshot.val());
for (var i = 0; i < offerKeys.length; i++) {
var offer = snapshot.val()[offerKeys[i]];
var lat = offer.lat;
var lng = offer.lng;
offers.push([lat, lng]);
var marker = L.marker([lat, lng]).addTo(markers);
}
map.fitBounds(markers.getBounds());
});
If it's called outside the callback, there won't be any markers in the feature group and the group's bounds won't be valid.
I'm trying to remove an array of GeoJson layers from Google Maps using the turf.js library for smoothing of the poly-lines.
I can create the layer fine and add them to the map, but when I try and remove the layers I get the following error code:
Uncaught TypeError: a.getId is not a function
To add the layers I do this, looping through my GeoJson file...
else if(Type==="LineString" && Pype==="isobar") {
//DO ISOBARS STUFF=================================
//GET LNG/LAT======================================
CorrLEN = dataID1.features[i].geometry.coordinates.length;
var Corrds =[];
var Corrs =[];
var LNGLAT ={};
var CORRS = new Object();
var x=0;
for (x=0;x<CorrLEN;x++){
var a = x-1;
LNGLAT = (dataID1.features[i].geometry.coordinates[x]);
Corrds.push(LNGLAT);
}
//=================================================================
//GET COLOUR INFO===================================================
var STCL = dataID1.features[i].properties.strokeColor;
var STOP = dataID1.features[i].properties.strokeOpacity;
var STSW = dataID1.features[i].properties.strokeWeight;
//=================================================================
LL = turf.linestring(Corrds);
curved = turf.bezier(LL,20000, 0.35);
curved.properties = {weight:STSW,color:STCL};
map.data.setStyle(function(feature) {
return {strokeWeight:feature.getProperty('weight'),
strokeColor: feature.getProperty('color')
};
});
IsoBars.push(curved);
I then use the following functions to add or remove the layers
//SHOW ISOBARS (works fine)
function ShowIsoBars() {
for (var i = 0; i < IsoBars.length; i++) {
map.data.addGeoJson(IsoBars[i]);
}}
//HIDE ISOBARS (Gets the error) Uncaught TypeError: a.getId is not a function
function HideIsoBars() {
for (var i = 0; i < IsoBars.length; i++) {
map.data.remove(IsoBars[i]);
}}
Many thanks in advance,
I found a solution by taking the new smoothed coordinates and then using them in a new google.maps.Polyline like so
var Path =[];
var x=0;
for (x=0;x<CorrLEN;x++){
Path.push(new google.maps.LatLng(curved.geometry.coordinates[x][1],curved.geometry.coordinates[x][0]));
}
var IsoBar = new google.maps.Polyline({
path: Path,
geodesic: true,
strokeColor: STCL,
strokeOpacity: STOP,
strokeWeight: STSW
});
IsoBars.push(IsoBar);
And then I can use the the following functions to show or hide the layers
function ShowIsoBars() {
for (var i = 0; i < IsoBars.length; i++) {
IsoBars[i].setMap(map);
}}
function HideIsoBars() {
for (var i = 0; i < IsoBars.length; i++) {
IsoBars[i].setMap(null);
}}
I found rather than removing all objects from the layer. It was easier to destroy and recreate the layer, which circumvents the error:
//Remove layer from map if it exists
if (mapLayer != null) {
mapLayer.setMap(null);
}
//create new layer
mapLayer = new window.google.maps.Data({ map: googleMap });
I'm trying to get the lat and lon from a Json encoded file for use as destinations for the distance Matrix API rather than add var destinationA = new google.maps.LatLng(??.????, ???.?????); multiple times.
I thought I managed it, as both ways seem to produce the same variable destinations when viewed, yet method two produces an error Uncaught TypeError: a.lat is not a function
This is method one which gives var destination a length of 7:
var destinationA = new google.maps.LatLng(13.7373393, 100.5558883);
var destinationB = new google.maps.LatLng(13.735132, 100.55611199999998);
var destinationC = new google.maps.LatLng(13.736953, 100.55819300000007);
var destinationD = new google.maps.LatLng(13.736244, 100.55694100000005);
var destinationE = new google.maps.LatLng(13.736166, 100.557203);
var destinationF = new google.maps.LatLng(13.738747, 100.55587700000001);
var destinationG = new google.maps.LatLng(13.733558, 100.56020699999999);
var destinations = [destinationA,destinationB,destinationC,destinationD,destinationE,destinationF,destinationG];
works great, will return the distances for each from a given centre point on google map.
Method two:
This is method Two which gives var destination a length of 1, which I am stuck on finding out why its a single length and not 7 as above:
var location_lat_lon = <?php echo json_encode( $properties_data ); ?>;
var destinations = []
var first = true;
for (var i=0; i < location_lat_lon.length; i++) {
var sep = first ? '' : ',';
var lat = location_lat_lon[i].latitude;
var lon = location_lat_lon[i].longitude;
var destination1 = new google.maps.LatLng(lat, lon);
var destinations = [destinations+sep+destination1] ;
first = false;
}
which returns exactly the same result when viewing the variable destinations, yet this returns the error Uncaught TypeError: a.lat is not a function.
Any advice or guidance?
Is it not possible to pass destinations this way to the calculateDistances function?
Thanks in Advance :)
Try this:
var location_lat_lon = <?php echo json_encode( $properties_data ); ?>;
var destinations = []
for (var i=0; i < location_lat_lon.length; i++) {
var lat = location_lat_lon[i].latitude;
var lon = location_lat_lon[i].longitude;
var destination1 = new google.maps.LatLng(parseFloat(lat), parseFloat(lon));
destinations.push(destination1);
}