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 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.
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
the following code is used to draw a polyline on Google Maps using V3 API, but sometimes is draws the polyline and most of times doesn't despite there are point (as I can show the points on the map as markers) but no polyline appears
update 2 : I am using openstreetmap layer over Google maps. does that cause the problem when drawing the polyilne ?
w variable contains data as string , for example :
w= 35.1212,55.2333\n36.32366,56.3333
Real data sample for w : [this code can draw markers for the following points but can't draw a polyline ]
34.440501,31.515222
34.441933,31.514346
34.44247,31.514013
34.442603,31.51394
34.443607,31.513423
34.4445,31.512926
34.444762,31.512772
34.445186,31.512523
34.445257,31.512481
34.445311,31.512449
34.445614,31.512264
34.446244,31.511867
34.446939,31.511429
34.447351,31.511193
34.448081,31.512174
34.448241,31.512357
34.448576,31.512741
34.449147,31.513185
34.4499,31.513723
34.450894,31.514401
34.451925,31.515362
34.452905,31.516176
34.454194,31.517266
34.455337,31.518236
34.456215,31.51898
34.456987,31.519646
34.457583,31.520166
34.458298,31.520772
34.458989,31.52139
34.459659,31.521959
34.460476,31.522653
34.461192,31.523228
34.461869,31.523788
34.46256,31.524376
34.463302,31.525015
34.464062,31.525668
34.464433,31.525986
34.464737,31.526246
34.465247,31.526683
34.465498,31.526907
34.466666,31.52792
34.46722,31.528404
34.467327,31.528495
34.468014,31.529081
34.468379,31.52939
34.469296,31.530177
34.469771,31.530583
34.470152,31.53091
34.470951,31.531597
34.471617,31.532172
34.472388,31.532838
34.472664,31.533076
34.47295,31.533397
34.473422,31.533653
34.474028,31.534065
34.474844,31.534629
34.475725,31.535253
34.476083,31.535517
34.476697,31.535947
34.477105,31.536209
34.477627,31.536477
34.478,31.536742
34.478398,31.536989
34.478935,31.537325
34.480044,31.537975
34.480985,31.538529
34.481362,31.53878
34.481416,31.538819
34.482407,31.539419
34.482682,31.539109
34.483132,31.538603
34.483341,31.538368
34.483917,31.537753
34.484202,31.537449
34.484288,31.537357
34.484944,31.536587
34.485118,31.536383
34.485205,31.536304
34.485648,31.535903
34.485984,31.535598
34.486246,31.535381
34.486445,31.535291
34.486533,31.535254
34.486607,31.535282
34.486706,31.535354
34.486869,31.535526
34.487012,31.535692
34.487212,31.535923
34.487273,31.536006
34.487767,31.53571
34.488336,31.535395
34.48883,31.535148
34.489078,31.535032
34.489354,31.534901
34.48955,31.534788
34.489756,31.535011
34.489831,31.535097
34.490268,31.534748
34.49065,31.534473
34.490857,31.53436
34.491044,31.534319
34.491352,31.534248
34.491458,31.534237
34.491548,31.534304
34.491879,31.534209
34.492227,31.534203
34.492457,31.534214
34.492042,31.533636
34.492162,31.533542
note : I have reversed lng and lat when creating a point for some purpose
where a is array that has the points to represent as a polyine
code
var mypolyline = new google.maps.Polyline({
strokeColor: "#FF0000",
strokeOpacity: .6,
strokeWeight: 3,
clickable: true
});
// var bounds2 = new google.maps.LatLngBounds();
var a=w.split("\n");
for(var i=0;i<a.length;i++)
{
var zz=a[i].split(",");
var lat=zz[0];
var lng=zz[1];
var path = [];
var path = mypolyline.getPath();
var point = new google.maps.LatLng(parseFloat(lng),parseFloat(lat));
createMarker(i,name,point,icon[1],2);
// alert(path.length);
path.push(point);
mypolyline.setPath(path);
mypolyline.setMap(map);
}
CreateMarker() function
function createMarker(id,name,point,icon,type) {
// var marker = new google.maps.Marker(point, customIcons[type]);
var marker = new google.maps.Marker({
map: map,
position: point,
icon: icon
});
markersArray.push(marker);
google.maps.event.addListener(marker, 'click', function() {
infowindow = new google.maps.InfoWindow({ content: name });
infowindow.open(map, marker);
map.panTo(point);
});
return marker;
}
So you create an array, then you ignore that and recreate it as an MVCArray using the getPath() function. Get rid of the first line (this isn't the cause of the problems though).
var path = [];
var path = mypolyline.getPath();
Just a thought - is the path a required attribute when you first create the polyline?
It seems to me that you initially create the mypolyline without any path. So when you then do this on the first iteration, it's not going to work, because all you're passing to .setPath() is one point, but I assume a path can only work when there's at least 2 points.
path.push(point);
mypolyline.setPath(path);
Update: I think the thing to do would be to just start out with an empty array, loop over your coordinates adding them into the array. Then after the loop, create the polyline, rather than trying to update it each time you iterate over the loop. For instance:
var a=w.split("\n");
var path = [];
for(var i=0;i<a.length;i++)
{
var zz=a[i].split(",");
var lat=zz[0];
var lng=zz[1];
var point = new google.maps.LatLng(parseFloat(lng),parseFloat(lat));
createMarker(i,name,point,icon[1],2);
path.push(point);
}
var mypolyline = new google.maps.Polyline({
path: path,
map: map,
strokeColor: "#FF0000",
strokeOpacity: .6,
strokeWeight: 3,
clickable: true
});
Sorry to bother you guys, but I'm stuck with his problem for half a day.
I want to draw poly line in OpenLayers using LineString object, so I've copied the example from documentation. It runs ok but i can't see the line on the screen
Code looks like this
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title></title>
<script type="text/javascript" src="http://openlayers.org/api/OpenLayers.js"></script>
<script src="http://www.openstreetmap.org/openlayers/OpenStreetMap.js"></script>
<script src='http://maps.google.com/maps?file=api&v=2&key=ABQIAAAAjpkAC9ePGem0lIq5XcMiuhR_wWLPFku8Ix9i2SXYRVK3e45q1BQUd_beF8dtzKET_EteAjPdGDwqpQ'></script>
<script type="text/javascript">
var map;
var lineLayer ;
var points;
var style;
var polygonFeature
function test()
{
lineLayer = new OpenLayers.Layer.Vector("Line Layer");
style = { strokeColor: '#0000ff',
strokeOpacity: 1,
strokeWidth: 10
};
map.addLayer(lineLayer);
points = new Array();
points[0] =new OpenLayers.LonLat(-2.460181,27.333984 ).transform(new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject());;
points[1] = new OpenLayers.LonLat(-3.864255,-22.5 ).transform(new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject());;
var linear_ring = new OpenLayers.Geometry.LinearRing(points);
polygonFeature = new OpenLayers.Feature.Vector(
new OpenLayers.Geometry.Polygon([linear_ring]), null, style);
lineLayer.addFeatures([polygonFeature]);
alert("1");
}
function initialize()
{
map = new OpenLayers.Map ("map_canvas", {
controls:[
new OpenLayers.Control.Navigation(),
new OpenLayers.Control.PanZoomBar(),
new OpenLayers.Control.LayerSwitcher(),
new OpenLayers.Control.Attribution()],
maxExtent: new OpenLayers.Bounds(-20037508.34,-20037508.34,20037508.34,20037508.34),
maxResolution: 156543.0399,
numZoomLevels: 19,
units: 'm',
projection: new OpenLayers.Projection("EPSG:900913"),
displayProjection: new OpenLayers.Projection("EPSG:4326")
});
// Define the map layer
// Here we use a predefined layer that will be kept up to date with URL changes
layerMapnik = new OpenLayers.Layer.OSM.Mapnik("Mapnik");
map.addLayer(layerMapnik);
var lonLat = new OpenLayers.LonLat(0, 0).transform(new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject());
map.zoomTo(3);
map.setCenter(lonLat, 19);
test();
}
</script>
</head>
<body onload="initialize()" >
<div id="map_canvas" style="width: 828px; height: 698px"></div>
</body>
</html>
I'm sure I'm missing some parameter in creation of map or something but I really can't figure which one.
You forget 's' character in this line:
lineLayer.addFeatures([lineFeature]);
Function 'addFeature' doesn't exist: OpenLayers.Layer.Vector.addFeatures
To see the feature, hold Shift key on your keyboard and try to draw a box
EDIT: Ok, now I know how did you want.
You need to create one OpenLayers.Point object for each point you have in your DB. One solution is to use and Ajax call to your own PHP function to retrieve them. The PHP file includes code to get them. I recommend to return them in JSON format (pherhaps an string). Using JQuery framework:
$.ajax({
url: 'your_php_file.php',
dataType: JSON // for example, you can use 'string' type too
success: function(coordinates){
}
});
Now you have a lot of coordinates from your DB. It's time to draw your polygon. Following link can be useful
OpenLayers - how do I draw a Polygon from existing lonLat points?
I hope it helps you. Happy codding!
EDIT2:
linear_ring is an object belongs to OpenLayers.Geometry.LinearRing class. The constructor needs an array of OpenLayers.Geometry.Points and you was giving it OpenLayers.LonLat array.
You need to modify this adding this line after each point creation (modifying the index according to you own code):
points[0] = new OpenLayers.Geometry.Point(points[0].lon,points[0].lat);
So your test function looks like this:
function test(){
lineLayer = new OpenLayers.Layer.Vector("Line Layer");
style = { strokeColor: '#0000ff',
strokeOpacity: 1,
strokeWidth: 10
};
points = new Array();
points[0] =new OpenLayers.LonLat(-2.460181,27.333984 ).transform(new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject());;
points[0] = new OpenLayers.Geometry.Point(points[0].lon,points[0].lat);
points[1] = new OpenLayers.LonLat(-3.864255,-22.5 ).transform(new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject());;
points[1] = new OpenLayers.Geometry.Point(points[1].lon,points[1].lat);
var linear_ring = new OpenLayers.Geometry.LinearRing(points);
polygonFeature = new OpenLayers.Feature.Vector(
new OpenLayers.Geometry.Polygon([linear_ring]), null, style);
lineLayer.addFeatures([polygonFeature]);
map.addLayer(lineLayer);
}
The result is this: Image result
Yes, OpenLayers can programatically draw lines. Its even fast enough to draw new lines multiple times a second so you can show live data or animations. Anyway, you have a lot of stuff going on in your code. Perhaps your style is messed up and drawing invisible lines, or your data points are getting transformed incorrectly and the line is off the map. Anyway, I suggest this simple test.
Create a map, and add a vector layer. hang on to the vector layer in a global var called layerVec. Then, run this code.
var CreateLine = function()
{
var pList = new Array();
for(var i=0; i<200; i++)
{
var p = new OpenLayers.Geometry.Point();
p.x = i;
p.y = i;
pList.push(p);
}
var g = new OpenLayers.Geometry.LineString(pList);
var f = new OpenLayers.Feature.Vector(g,null,null);
layerVec.addFeatures(f);
};
Dont worry about coordinates yet, this should be a line in the middle of the map. It may be tiny, or huge depending on your projection, so zoom in.