have a web page which displays weather charts from many sources. You pick your source and outlines of the charts appear on a Google Map. (See http://www.geoffschultz.org/weather_map.php Weather Charts/GMDSS/Forecasts - should draw 3 polygons) Up until now all of the charts have been rectangular, but I just came across the need for non-rectangular charts. I had coded the js with this in mind, but I have been baffled because only the last polygon drawn is displayed. Is there something that I'm missing with regards to multiple polygons?
The code is very simple. It gets an array of bounding box coordinates. For simple rectangles the array element looks like "-31,-32|2,25" and for polygons it just has more coordinates separated by "|". If there are 2 coordinates, I draw a rectangle, otherwise I draw a polygon, closing it with the 1st point.
What am I doing wrong as it works great for rectangles?
-- Geoff
for (i in bb[selValue])
{
bb_lat_long = bb[selValue][i]["bb_lat_long"].split("|");
if (bb_lat_long.length == 2) //Rectangle
{
lat_long = bb_lat_long[0].split(",");
sw = new google.maps.LatLng(lat_long[0], lat_long[1]);
lat_long = bb_lat_long[1].split(",");
ne = new google.maps.LatLng(lat_long[0], lat_long[1]);
bounds = new google.maps.LatLngBounds(sw, ne);
bounding_box = new google.maps.Rectangle({map: map, bounds: bounds, fillOpacity: 0.05, strokeWeight: 1});
}
else // polygon
{
poly_lat_long.length = 0;
for (j = 0; j < bb_lat_long.length; j++)
{
lat_long = bb_lat_long[j].split(",");
poly_lat_long.push(new google.maps.LatLng(lat_long[0], lat_long[1]));
}
lat_long = bb_lat_long[0].split(",");
poly_lat_long.push(new google.maps.LatLng(lat_long[0], lat_long[1])); // close polygon with 1st point
bounding_box = new google.maps.Polygon({map: map, paths: poly_lat_long, fillOpacity: 0.05, strokeWeight: 1});
}
}
My suspicion is that it has to do with re-using the path in the new polygons (you are ending up with multiple polygons, the just all are the same, perhaps if you declare poly_lat_long locally (with var), or make a createPolygon function that would get function closure on the path.
I have seen this behavior before when clearing the path array using poly_lat_long.length = 0;
rather than creating a new array (poly_lat_long = []).
Thread from the Google Maps API v3 group discussing similar problem
Related
I'm currently really confused, and I do need an advice.
My current aim is to get a Satellite view of a random building, with the tipical RoadMap\3d effect of Google maps:
and being able to use three.js on it, rendering polys overlapping that map.
I've followed example from this git repo:
ubilabs/google-maps-api-threejs-layer
But I can include particles on a map...I can't put on it geometries like polygons, splines and such.
I don't know what to do know...maybe Cesium is the answer?
But Cesium doesn't have the same "3d" option on buildings...
Any help would be appreciated!
Thanks!
For polygon, line and marker you can use google maps v3
You can see this link google developer link for a firts evaluation
i'm talking about native polygon , polyline, marker . or native drwing tools of google maps v3
https://developers.google.com/maps/documentation/javascript/examples/drawing-tools and https://developers.google.com/maps/documentation/javascript/examples/polygon-simple
but more useful is this link Dyer
http://johndyer.name/drawing-3d-objects-and-building-on-google-maps/
where with proper function you can build your 3d object
function drawExcrudedShape(map, coordinates, height, strokeColor, strokeOpacity, strokeWeight, fillColor, fillOpacity) {
var pairs = [],
polygons = [];
// build line pairs for each wall
for (var i=0; i<coordinates.length; i++) {
var point = coordinates[i],
otherIndex = (i == coordinates.length-1) ? 0 : i+1,
otherPoint = coordinates[otherIndex];
pairs.push([point, otherPoint]);
}
// draw excrusions
for (var i=0; i<pairs.length; i++) {
var first = pairs[i][0],
second = pairs[i][1],
wallCoordinates = [
new google.maps.LatLng(first[0],first[1]),
new google.maps.LatLng(first[0]+height,first[1]),
new google.maps.LatLng(second[0]+height,second[1]),
new google.maps.LatLng(second[0],second[1])
],
polygon = new google.maps.Polygon({
paths: wallCoordinates,
strokeColor: strokeColor,
strokeOpacity: strokeOpacity,
strokeWeight: strokeWeight,
fillColor: fillColor,
fillOpacity: fillOpacity
zIndex: zIndexBase+i
});
polygon.setMap(map);
polygons.push(polygon);
}
return polygons;
}
I have a project which consist in visualizing the exchange of data between points on a map.
I'm using Leaflet to draw polylines from coordinates in a GeoJson file and Leaflet.polylineDecorator (https://github.com/bbecquet/Leaflet.PolylineDecorator) to put an animated arrow on the polyline.
The thing is that I need to visualize the stream in both directions. I started by adding to my Geojson file polylines in the other direction but the issue is when I zoom out, the two polylines are stacked.
So I found Leaflet.polylineOffset (https://github.com/bbecquet/Leaflet.PolylineOffset) which allows to create an another polyline just by setting the offset option.
I thought, i just had to do the same to put the animated arrow on it but when i'm doing it, the animation is affected to the original polyline. In fact, the offset polyline keeps the coordinates from the original one.
I wanted to know if there is a way to apply this animation to the offset polyline.
Here is my code:
d3.json("data/trajetsFibreDCSigma.json",function (data){ // getting polylines' data from a json file to add them on the map
L.geoJson(data, {
style: function(feature){return {color : feature.properties.stroke,opacity: 1};}, // setting the style of the polylines
onEachFeature: function(feature){
// getting the coordinates of the polyline from the json file
var latlng = feature.geometry.coordinates;
var size = feature.geometry.coordinates.length;
var buffer;
// reversing the order of latitude and longitude in the array because a L.latLng object needs the latitude first and I have the opposite in my json file
for (i=0;i<size;i++)
{
buffer = latlng[i][0];
latlng[i][0] = latlng[i][1];
latlng[i][1] = buffer;
}
var polylineOffset = L.polyline(latlng,{offset: 5,color: 'blue',opacity: 1}).addTo(map); // putting an offset to the polyline
addArrow(latlng,feature);
addArrow(polylineOffset,feature);
}
}).addTo(map);
});
function addArrow(polyline,feature){ // function to add an arrow on the map
var arrowHead = L.polylineDecorator(polyline).addTo(map); // creating an arrow which will be put on the polyline
var arrowOffset = 0;
window.setInterval(function() { // creating an animation for the arrow to cross the polyline
arrowHead.setPatterns([
{offset: arrowOffset+'%', repeat: 0, symbol: L.Symbol.arrowHead({pixelSize: 10, polygon: false,
pathOptions: {stroke: true,color: feature.properties.stroke,opacity: 1}})}
]);
if(++arrowOffset > 100)
arrowOffset = 0;
}, 100);
}
(If I'm just calling addArrow with the offset polyline, it will pop on the original one).
I found a solution to get the offset polyline's coordinates.
The PolylineOffset plugin has a function which returns the offset coordinates.
You can use it like this:
var pts = L.PolylineOffset.offsetLatLngs(latlng,10,map); // getting the coordinates from the offset polyline
where latlng is the array of the original coordinates
; 10 is the offset
; map is your leaflet map
I want to create a hole in my Javascript Google API V3, so i follow Beginning Google Map API V3. But the code is rendering the whole area. Here is my Javascript code.
(function() {
window.onload = function() {
// Creating a map
var options = {
zoom: 6,
center: new google.maps.LatLng(36.5, -79.8),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById('map'), options);
// Creating an array with the points for the outer polygon
var polyOuter = [
new google.maps.LatLng(37.303, -81.256),
new google.maps.LatLng(37.303, -78.333),
new google.maps.LatLng(35.392, -78.333),
new google.maps.LatLng(35.392, -81.256)
];
// Creating an array with the points for the inner polygon
var polyInner = [
new google.maps.LatLng(36.705, -80.459),
new google.maps.LatLng(36.705, -79),
new google.maps.LatLng(35.9, -79),
new google.maps.LatLng(35.9, -80.459)
];
var points = [polyOuter, polyInner];
// Creating the polygon
var polygon = new google.maps.Polygon
({
paths: points,
map: map,
strokeColor: '#ff0000',
strokeOpacity: 0.6,
strokeWeight: 3,
fillColor: '#FF0000',
fillOpacity: 0.35
});
};
})();
One of the paths has to be reverted so polygons are drawn in different directions, for example:
var polyInner = [
new google.maps.LatLng(35.9, -80.459),
new google.maps.LatLng(35.9, -79),
new google.maps.LatLng(36.705, -79),
new google.maps.LatLng(36.705, -80.459)
];
My assumption is that the reason is how SVG or canvas render closed loops. If I am not wrong explanation lies in nonzero winding rule. See explanation at wikipedia.
Outer path is drawn clockwise, inner path is drawn counter-clockwise.
Set a counter to zero. Pick a point in object area and draw a line in direction out of object space. If the line cross clockwise path, add one. If the line cross counter-clockwise path segment, subtract one. If the final result for selected point is non-zero, the browser fills the area. If the final result is zero, the browser does not fill it.
So, if you pick up point in the 'hole', the result will be zero and area will not be filled.
I am traking user movement according to their latitude and longitude.so for last 1hr i got more than 20 coordinates.Using that co-ordinates i am drawing the map using google map api.I got one curly line(user's movement graph) and i want the get the distance from the staring point to ending point.
these are my co-ordinates:-
[[12.938419, 77.62224],
[12.938494, 77.622377],
[12.938369, 77.622449],
[12.938345, 77.622521],
[12.938322, 77.622575],
[12.938346, 77.622631],
[12.938306, 77.622648],
[12.938299, 77.622695],
[12.938254, 77.622715],
[12.938242, 77.622761],
[12.938227, 77.622805],
[12.93819, 77.622792],
[12.938138, 77.622837],
[12.938129, 77.622887],
[12.938103, 77.622949],
[12.938066, 77.622989],
[12.938006, 77.622966],
[12.937933, 77.623001],
[12.937976, 77.623073],
[12.937954, 77.623128],
[12.937912, 77.623111],
[12.937882, 77.623034],
[12.937933, 77.623001],
[12.938006, 77.622966],
[12.937921, 77.62293]]
Get the distance between each set of points using google.maps.geometry.spherical.computeDistanceBetween (convert each point to a google.maps.LatLng first). Sum those distances for the total.
Or use the google.maps.geometry.spherical.computeLength method on an array of google.maps.LatLng objects created from your coordinates.
fiddle
for (var i=0; i < coordinates.length; i++) {
path.push(new google.maps.LatLng(coordinates[i][0],
coordinates[i][1]));
}
var polyline = new google.maps.Polyline({
path: path,
map: map,
strokeWeight: 2,
strokeColor: "blue"
});
var length = google.maps.geometry.spherical.computeLength(polyline.getPath());
document.getElementById('length').innerHTML = "length="+(length/1000).toFixed(2)+ " km";
I have seen the examples presented here of how to draw a line but the examples only show how to do it with the mouse, by clicking.
What I want to do is draw the line manually using JavaScript given a list of Longitude and Latitude coordinates.
The reason I cannot work on the source provided in the link above is because they are only calling activate on the feature, and then let the user point and click on the map.
Has anyone ever drew a path on an OpenLayers map programatically?
What I want to do is exactly this: http://openspace.ordnancesurvey.co.uk/openspace/example4.html, but without using OpenSpace.
You would need to make use of the LineString object
Here is an example:
var lineLayer = new OpenLayers.Layer.Vector("Line Layer");
map.addLayer(lineLayer);
map.addControl(new OpenLayers.Control.DrawFeature(lineLayer, OpenLayers.Handler.Path));
var points = new Array(
new OpenLayers.Geometry.Point(lon1, lat1),
new OpenLayers.Geometry.Point(lon2, lat2)
);
var line = new OpenLayers.Geometry.LineString(points);
var style = {
strokeColor: '#0000ff',
strokeOpacity: 0.5,
strokeWidth: 5
};
var lineFeature = new OpenLayers.Feature.Vector(line, null, style);
lineLayer.addFeatures([lineFeature]);
Assuming map is your map object and lon and lat are float values.