Geometry (CONVOLUTION) function with javascript or jquery - javascript

I try to do this 3 months - I need to create a polygon by route direction like here:
so so I write this:
directionService.route(request, function(result, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsRenderer.setDirections(result);
var r = [];
var z = 0.5;
var bla = result.routes[0].overview_path;
for(var i=0 in result.routes[0].overview_path) {
r.push(new google.maps.LatLng(bla[i].lat()+z, bla[i].lng()-z));
}
bla.reverse();
for(var x=0 in bla) {
r.push(new google.maps.LatLng(bla[x].lat()-z, bla[x].lng()+z));
}
var prva = new google.maps.Polyline({
path: result.routes[0].overview_path,
strokeColor: "#00000",
strokeOpacity: 1.0,
strokeWeight: 2
});
prva.setMap(map);
druga = new google.maps.Polygon({
paths: r,
strokeColor: "#FF0000",
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: "#FF0000",
fillOpacity: 0.35
});
druga.setMap(map);
} else {
alert("Directions query failed: " + status);
}
});
but in some cases is good in some cases not, so my code produce this:
BAD case:
GOOD case:
So how I can solve this problem to get nice polygon by route direction ??? Does someody have idea?
How I can implement this into my code:
CONVOLUTION ALGORITHM
Is there any solution for my problem?
Is there some other way than this to create what I need?

The algorithm to produce the second image is quite simple geometrically. I'll write you some pseudocode, assuming you have an array of x,y arrays:
coordinates = [[x1,y1],[x2,y2] ... [xn,yn]]
leftcoords = []
rightcoords = []
projectionwidth = 1 # How wide the path is
for each coordinate in coordinates:
pathvector = coordinate(index + 1) - coordinate(index - 1)
normpathvector = pathvector/(length(pathvector))
perpvector = projectionwidth*[-normpathvector[1],normpathvector[0]]
leftcoords.append(coordinate + perpvector)
rightcoords.append(coordinate - perpvector)
You have to take care at the end of the path to only choose coordinates ahead or behind, but you get the idea. You end up with three sets of coordinate trajectories. You can set it up to average several points if you'd like to smooth the path.
Ok, so here is code that works, but you'll have to do some work to smooth it out to account for the jitter in the path. My suggestion would be to average several previous points, or just grab a point several back.
http://jsbin.com/uTATePe/2/

Related

removing the polygon based on checkbox toggle

please look into the image for reference
when i select the checkbox i am calling the getTerritory function from toggleTerritory(),that draws the polygon.But the problem i am facing is, i am not able to clear the polygon when checkbox is unselected.
Can anyone help me in doing this.
toggleTerritory function is below
$scope.toggleTerritory = function(item, list) {
var idx = list.indexOf(item);
if (idx > -1) {
list.splice(idx, 1);
//How to clear the polygon here
}
else {
list.push(item);
$scope.getTerritory(item);//this creates the polygon
}
};
$scope.drowTerritory={};
$scope.getTerritory= function (territory_id) {
setTimeout(function(){
$scope.drowTerritory= _.find($scope.territory, function(o) {
return o.territory_id === territory_id;
});
console.log("$scope.drowTerritory");
console.log($scope.drowTerritory.geometry);
//Edit Territory
console.log("$scope.drowTerritory");
console.log($scope.drowTerritory.geometry);
var wkt=$scope.drowTerritory.geometry.replace(/, /g, ",");
console.log("wktnewwwww");
console.log(wkt);
var regex = /\(([^()]+)\)/g;
var Rings = [];
var results;
while( results = regex.exec(wkt) ) {
console.log("wkt");
console.log(wkt);
Rings.push( results[1] );
}
var ptsArray=[];
var polyLen=Rings.length;
//now we need to draw the polygon for each of inner rings, but reversed
for(var i=0;i<polyLen;i++){
AddPoints(Rings[i]);
}
poly = new google.maps.Polygon({
paths:ptsArray,
strokeColor: '#1E90FF',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#1E90FF',
fillOpacity: 0.35,
editable: false,
});
poly.setMap(map);
//function to add points from individual rings
function AddPoints(data){
var pointsData=data.split(",");
var len=pointsData.length;
console.log("len");
console.log(len);
for (var i=0;i<len;i++)
{
var xy=pointsData[i].split(" ");
var pt=new google.maps.LatLng(xy[1],xy[0]);
ptsArray.push(pt);
};
}
},1000);
};
From this documentation, o remove a polygon from the map, call the setMap() method passing null as the argument. In the following example, bermudaTriangle is a polygon object:
bermudaTriangle.setMap(null);
Note that the above method does not delete the polygon. It simply removes the polygon from the map. If instead you wish to delete the polygon, you should remove it from the map, and then set the polygon itself to null.
Check this SO question, I think it can help you a lot.

Tiling contiguous polygons in Google Maps

I'm trying to draw a hexagonal grid in Google Maps. I've come up with a solution based off this answer which looks fine at higher zooms, but when zoomed further out I find that the classic "orange-peel" problem occurs: The hexagons no longer fit together like they should:
I'm using this rather cool geodesy library to calculate hexagon centers based on an ellipsoidal model (since a 2d model clearly doesn't work on a real-world map) but it's still looking pretty bad when zoomed out.
Preferably, I'd like to draw the hexagons in such a way that they are exactly the same shape and size on screen.
Here's the code I've been working with, also available as a Plunker here. I've tried calculating the vertices of each polygon using the same geodesy library that I'm using to calculate the polygon centers, but it still doesn't look right when zoomed out.
var hexgrid = [];
function initialize(){
// Create the map.
var map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 51.5, lng: 0},
scrollwheel: true,
zoom: 8
});
// This listener waits until the map is done zooming or panning,
// Then clears all existing polygons and re-draws them.
map.addListener('idle', function() {
// Figure out how big our grid needs to be
var spherical = google.maps.geometry.spherical,
bounds = map.getBounds(),
cor1 = bounds.getNorthEast(),
cor2 = bounds.getSouthWest(),
cor3 = new google.maps.LatLng(cor2.lat(), cor1.lng()),
cor4 = new google.maps.LatLng(cor1.lat(), cor2.lng()),
diagonal = spherical.computeDistanceBetween(cor1,cor2),
gridSize = diagonal / 20;
// Determine the actual distance between tiles
var d = 2 * gridSize * Math.cos(Math.PI / 6);
// Clear all the old tiles
hexgrid.forEach(function(hexagon){
hexagon.setMap(null);
});
hexgrid = [];
// Determine where the upper left-hand corner is.
bounds = map.getBounds();
ne = bounds.getNorthEast();
sw = bounds.getSouthWest();
var point = new LatLon(ne.lat(), sw.lng());
// ... Until we're at the bottom of the screen...
while(point.lat > sw.lat()){
// Keep this so that we know where to return to when we're done moving across to the right
leftPoint = new LatLon(point.lat, point.lon).destinationPoint(d, 150).destinationPoint(d, 210).destinationPoint(d, 270).destinationPoint(d, 90)
step = 1;
while(point.lon < ne.lng()){
// Use the modulus of step to determing if we want to angle up or down
if (step % 2 === 0){
point = new LatLon(point.lat, point.lon).destinationPoint(d, 30);
} else {
point = new LatLon(point.lat, point.lon).destinationPoint(d, 150);
}
step++; // Increment the step
// Draw the hexagon!
// First, come up with the corners.
vertices = [];
for(v = 1; v < 7; v++){
angle = v * 60;
vertex = point.destinationPoint(d / Math.sqrt(3), angle);
vertices.push({lat: vertex.lat, lng: vertex.lon});
}
// Create the shape
hexagon = new google.maps.Polygon({
map: map,
paths: vertices,
strokeColor: '#090',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#090',
fillOpacity: 0.1,
draggable: false,
});
// Push it to hexgrid so we can delete it later
hexgrid.push(hexagon)
}
// Return to the left.
point = leftPoint;
}
});
}
google.maps.event.addDomListener(window, 'load', initialize);
Please consider that Google Maps is in Mercator Projection.
You have to compensate for the sphere of the globe on the projection.
https://en.wikipedia.org/wiki/Mercator_projection

Is it possible to remove the border from RouteBoxer-boxes?

EDIT This question has been answered but I've clarified it for future readers.
RouteBoxer provides a solution of 'boxing in' a route in Google maps so that I can list various points of interest along that route. This technic though creates borders around each box presented on the map. I've attached an image to describe what it looks like.
The code produced to create RouteBoxer looks like this:
<script type="text/javascript" src="http://google-maps-utility-library-v3.googlecode.com/svn/trunk/routeboxer/src/RouteBoxer.js"></script>
var directionService = new google.maps.DirectionsService();
var rboxer = new RouteBoxer();
var distance = 20; // km
directionService.route(request, function(result, status) {
if (status == google.maps.DirectionsStatus.OK) {
// Box the overview path of the first route
var path = result.routes[0].overview_path;
var boxes = routeBoxer.box(path, distance);
for (var i = 0; i < boxes.length; i++) {
var bounds = box[i];
// Perform search over this bounds
}
}
});
Is it possible to remove the borders surrounding each box on the map?
You have full control. Here is the example above in a fiddle, without black borders -> http://jsfiddle.net/ftgr8dyp/ Look at the function drawBoxes() :
function drawBoxes(boxes) {
boxpolys = new Array(boxes.length);
for (var i = 0; i < boxes.length; i++) {
boxpolys[i] = new google.maps.Rectangle({
bounds: boxes[i],
fillOpacity: 0,
strokeOpacity: 1.0,
strokeColor: '#000000', //<-- change color
strokeWeight: 0, //<-- change strokeWeight from 1 to 0
map: map
});
}
}
It is standard google.maps.Rectangle's you can style as you are used to. There is nothing in the RouterBoxer-code that forces certain design or styles.

use JSON.stringify and JSON.parse to store polygon coordinates into oracle

I want to store the coordinates of a google maps polygon overlay into oracle and display it on next session. There is the code:
function savePolygons(){
$.post('oracle_deletePolygons.php');
for (var i = 0; i < createdShapes.length; i++){
var nom_zone = escape(document.getElementById('nom_zone_' + createdShapes[i].id).value);
var couleur = escape(createdShapes[i].fillColor);
var code_cs = escape('711');
var shapeid_export = escape(createdShapes[i].id);
var geometry = createdShapes[i].getPath().getArray();
geometry = JSON.stringify(geometry);
var url1 = "oracle_savePolygons.php?nom_zone=" + nom_zone + "&couleur=" + couleur + "&code_cs=" + code_cs + "&shapeid_export=" + shapeid_export + "&geometry=" + geometry;
$.get(url1);
}
}
I use JSON.stringify to convert into text the path array of the polygon which return this:
[{"Ya":53.4357192066942,"Za":-75.82763671875},{"Ya":52.40241887397331,"Za":-77.3876953125},{"Ya":51.781435604431195,"Za":-74.0478515625}]
After using php to parse the data of the oracle table into javascript var, I use JSON.parse to convert the string back to array of coordinates like that in order to rebuild the polygons:
function addPolygons(shapeId_import, nom_zone, couleur, geometry){
geometry = JSON.parse(geometry);
var newPolygon = new google.maps.Polygon({
paths: geometry,
fillColor: couleur,
fillOpacity: 0.45,
strokeWeight: 1,
editable: false,
shapeid: shapeId_import,
map:map
});
Unfortunately, its not working. I cant rebuild polygon with this new array. Can you tell me how to rebuild the polygon that way?
JSON.stringify() will not keep the original MVCArray, the constructor is missing.
You better use google.maps.geometry.encoding.encodePath() to create a storable value and decode it before re-using it.

Letting users draw curved lines on a google map?

Does anyone have any examples or source for letting users draw curved maps from point a to point b?
Thanks,
Alex
You can draw Bezier curves this way:
var GmapsCubicBezier = function(lat1, long1, lat2, long2, lat3, long3, lat4, long4, resolution, map){
var points = [];
for(it = 0; it <= 1; it += resolution) {
points.push(this.getBezier({x:lat1, y:long1},{x:lat2, y:long2},{x:lat3, y:long3},{x:lat4, y:long4}, it));
}
for(var i = 0; i < points.length - 1; i++) {
var Line = new google.maps.Polyline({
path: [new google.maps.LatLng(points[i].x, points[i].y), new google.maps.LatLng(points[i+1].x, points[i+1].y)],
geodesic: true,
strokeOpacity: 0,
strokeColor: 'yellow',
icons: [{
icon: {
path: 'M 0,-2 0,2',
strokeColor: 'violet',
strokeOpacity: 1,
strokeWeight: 4
},
repeat: '36px'
},{
icon: {
path: 'M -1,-2 -1,2',
strokeColor: 'black',
strokeOpacity: 1,
strokeWeight: 2
},
repeat: '36px'
}]
});
Line.setMap(map);
}
};
GmapsCubicBezier.prototype = {
B1 : function (t) { return t*t*t; },
B2 : function (t) { return 3*t*t*(1-t); },
B3 : function (t) { return 3*t*(1-t)*(1-t); },
B4 : function (t) { return (1-t)*(1-t)*(1-t); },
getBezier : function (C1,C2,C3,C4, percent) {
var pos = {};
pos.x = C1.x*this.B1(percent) + C2.x*this.B2(percent) + C3.x*this.B3(percent) + C4.x*this.B4(percent);
pos.y = C1.y*this.B1(percent) + C2.y*this.B2(percent) + C3.y*this.B3(percent) + C4.y*this.B4(percent);
return pos;
}
};
You can modify the code, to provide differents strategies to draw the lines. The one implemented is pointed with "shadow".
The usage is pretty easy:
var curvedLine = new GmapsCubicBezier(initLat, initLong, control1Lat, control1Long, control2Lat, control2Long, endLat, endLong, 0.1, map);
you might have to use some sort of layer on top of google map. I know there's a cloud app that allows you to scrabble on a google map, but it uses flash to embed the google map scribblemaps.com/… i don't think it's possible to use two points to create a curve perhaps more than two points.
If i understand your application correctly, based on your website, the goal that you wish to achieve is to let users to "blaze a trail"? If that is the case maybe you can create a form where the users can submit Lat Lng coordinates of the "trials" that they've "blazed," and then use Polyline to draw the curve line similar to this google map draw curved line.
However, if users just want to know how to hike from point a to point b and etc, then you can use DirectionService and DirectionRenderer, and set the DirectionsTravelMode to google.maps.DirectionsTravelMode.WALKING and render the direction on the map that way so the user would know how to hike a route with directions drawn on the map + actual direction instructions.

Categories