I have tried lots but could not figure out the problem. I want to draw a polygon around specific lat,lng. The polygon will consists of 13 coordinates in specific radius.
Person inter the address and radius in text box.
Geo code get lat,lng of that address
Center the map to there.
Draw the polygon around that center point with radius
The polygon should consists of 13 coordinates
Code
function showAddress(address, miles) {
var geocoder = new google.maps.Geocoder();
geocoder.geocode({
address : address
}, function(results, status) {
if(status == google.maps.GeocoderStatus.OK) {
//searchLocationsNear(results[0].geometry.location);
var cordinate = results[0].geometry.location;
//alert(cordinate);
var mapOptions = {
center : cordinate,
zoom : 8,
mapTypeId : google.maps.MapTypeId.ROADMAP,
overviewMapControl : true,
overviewMapControlOptions : {
opened : true,
position : google.maps.ControlPosition.BOTTOM_LEFT
}
};
//
//var address = document.getElementById("address").value;
var radius = 1;
var latitude = 23.1793013;
var longitude = 75.78490970000007;
//Degrees to radians
var d2r = Math.PI / 180;
// Radians to degrees
var r2d = 180 / Math.PI;
// Earth radius is 3,963 miles
var cLat = (radius / 3963) * r2d;
var cLng = cLat / Math.cos(latitude * d2r);
//Store points in array
var points = [];
alert("declare array");
var bounds = new google.maps.LatLngBounds();
// Calculate the points
// Work around 360 points on circle
for(var i = 0; i < 13; i++) {
var theta = Math.PI * (i / 180);
// Calculate next X point
circleY = longitude + (cLng * Math.cos(theta));
//console.log("CircleY:"+circleY);
// Calculate next Y point
circleX = latitude + (cLat * Math.sin(theta));
//console.log("circleX:"+circleX);
// Add point to array
var aPoint = new google.maps.LatLng(circleX, circleY);
points.push(aPoint);
bounds.extend(aPoint);
}
points.push(points[0]);
//console.log(points);
//to complete circle
var colors = ["#CD0000", "#2E6444", "#003F87"];
var Polyline_Path = new google.maps.Polyline({
path : points,
strokeColor : colors[0],
// color of the outline of the polygon
strokeOpacity : 1,
// between 0.0 and 1.0
strokeWeight : 1,
// The stroke width in pixels
fillColor : colors[1],
fillOpacity : 0
});
var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
Polyline_Path.setMap(map);
} else {
alert(address + ' not found');
}
});
}
Replace i<13;i++ by
i<360;i+=360/13
this will work
thank
edit: the last point isn't needed since gmap will close it automagically
I believe that cLng should be changed to:
var cLng = cLat * Math.cos(latitude * d2r);
(to get a perfect circle, that is)
Related
I have plotted few markers and a polygon objects on Here Map.
I want to know the distance between the polygon and marker. Marker that is very nearer to polygon is what I want to figure out.
Here map has a distance function, but its only working to calculate distance between 2 markers.
Here is the function that I used to calculate distance PaohaIsland.getGeometry().distance(yosmitePark.getGeometry()) Where PaohaIsland is marker Object and yosmitePark is polygon object
var map;
function loadMap(){
platform = new H.service.Platform({
'apikey': HEREMAP_KEY
});
// Obtain the default map types from the platform object:
var defaultLayers = platform.createDefaultLayers();
// Instantiate (and display) a map object:
map = new H.Map(
document.getElementById('mapContainer'),
defaultLayers.vector.normal.map,
{
center: { lat: 37.278419, lng: -119.674072,
pixelRatio: window.devicePixelRatio || 1 },
zoom: 8
}
);
// Enable the event system on the map instance:
var mapEvents = new H.mapevents.MapEvents(map);
var behavior = new H.mapevents.Behavior(mapEvents);
behavior.enable(H.mapevents.Behavior.WHEELZOOM);
}
function addPolygonToMap() {
var lineString2 = new H.geo.LineString();
lineString2.pushPoint({lat:37.278419,lng:-119.674072});
lineString2.pushPoint({lat:37.335224,lng:-119.30603});
lineString2.pushPoint({lat:37.529331,lng:-119.198914});
lineString2.pushPoint({lat:37.522789,lng:-118.99292});
lineString2.pushPoint({lat:37.627281,lng:-118.87207});
lineString2.pushPoint({lat:37.80978,lng:-119.053337});
lineString2.pushPoint({lat:38.01347,lng:-119.143982});
lineString2.pushPoint({lat:37.965851,lng:-119.770203});
lineString2.pushPoint({lat:37.898689,lng:-120.18219});
lineString2.pushPoint({lat:37.867802,lng:-120.341492});
lineString2.pushPoint({lat:37.746819,lng:-120.239861});
lineString2.pushPoint({lat:37.51844,lng:-120.07782});
lineString2.pushPoint({lat:37.278419,lng:-119.674072});
var yosmitePark = new H.map.Polygon(lineString2, {
style: {
strokeColor: '#829',
lineWidth: 8
}
});
map.addObject(yosmitePark);
var lakeMcClure = new H.map.Marker({
lat: 37.6373862,
lng: -120.3448606
});
lakeMcClure.setData("lakeMcClure");
var Stockton = new H.map.Marker({
lat: 37.9729404,
lng: -121.4419639
});
Stockton.setData("Stockton");
var Monolake = new H.map.Marker({
lat: 38.0067483,
lng: -119.1013779
});
Monolake.setData("Monolake");
var PaohaIsland = new H.map.Marker({
lat: 38.000514,
lng: -119.0416587
});
PaohaIsland.setData("PaohaIsland");
var WalkerLake = new H.map.Marker({
lat: 38.7010578,
lng: -118.878652
});
WalkerLake.setData("WalkerLake");
var Bakersfield = new H.map.Marker({
lat: 35.3208963,
lng: -119.1587737
});
Bakersfield.setData("Bakersfield");
var SanFrancisco = new H.map.Marker({
lat: 37.7576793,
lng: -122.5076405
});
SanFrancisco.setData("SanFrancisco");
map.addObjects([lakeMcClure,Stockton,Monolake,PaohaIsland,WalkerLake,Bakersfield,SanFrancisco]);
var mapObj = map.getObjects();
console.log(yosmitePark.getGeometry());
console.log(PaohaIsland.getGeometry().distance(yosmitePark.getGeometry()));
}
There is no method in the API to calculate distance from point to polygon.
In order to achieve this, you can calculate distance from the point to each segment of the polygon's exterior LineString and then choose the smallest calculated value:
function distanceToGeoPolygon(geoPoint, geoPolygon) {
let lineString = geoPolygon.getExterior(),
minDistance = Infinity;
// check distance for each LineString segment of the polygon
for (let i = 0; i < lineString.getPointCount() - 1; i++) {
let segmentStart = lineString.extractPoint(i),
segmentEnd = lineString.extractPoint(i + 1),
distance = distanceToSegment(geoPoint, segmentStart, segmentEnd);
// set new min distance
if (distance <= minDistance) {
minDistance = distance;
}
}
return minDistance;
}
here is method to calculate distance from point to segment:
function distanceToSegment(point, segmentStart, segmentEnd) {
// first we find the intersecting point of line which
// crosses the given point and is vertical to segment (start - end)
let y0 = point.lat,
x0 = point.lng,
y1 = segmentStart.lat,
x1 = segmentStart.lng,
y2 = segmentEnd.lat,
x2 = segmentEnd.lng,
a = (y2 - y1) / (x2 - x1),
b = y1 - a * x1,
b0 = y0 + 1/a * x0,
xi = a * (b0 - b) / ((a * a) + 1),
yi = a * xi + b,
intersectingPoint = new H.geo.Point(yi, xi);
// if calculated intersecting point is within the segment,
// calculate distance between intersecting point and given point
if ( (xi > x1 && xi < x2 || xi > x2 && xi < x1) &&
(yi > y1 && yi < y2 || yi > y2 && yi < y1) ) {
return point.distance(intersectingPoint)
} else {
// else calculate distance between segment edges and given point
// and return the smaller one
return Math.min(point.distance(segmentStart), point.distance(segmentEnd));
}
}
test:
// test: (result is 14359)
console.log(distanceToGeoPolygon(lakeMcClure.getGeometry(), yosmitePark.getGeometry()));
Note: Above script returns positive numbers for points inside polygon too. If you don't want that, you can use H.Map#getObjectsWithin to verify if given Marker object (must be placed on map) is inside geo polygon (in your case I assume you don't need it).
Here is working jsfiddle example. It logs distance in the console after clicking on Marker object.
Trying to make the similar effect on my Googlemaps map.
This is using Ionic Native Google Maps plugin.
I currently have the following code.
Points are used to create an overlaying polygon across the whole map, and then I am using the drawCircle function to draw a circle by adding lat / lng points to the array extp.push({lat: ey,lng: ex});
points = [
{lat: 85,lng: 90},
{lat: 85,lng: 0.1},
{lat: 85,lng: -90},
{lat: 85,lng: -179.9},
{lat: 0,lng: -179.9},
{lat: -85,lng: -179.9},
{lat: -85,lng: -90},
{lat: -85,lng: 0.1},
{lat: -85,lng: 90},
{lat: -85,lng: 179.9},
{lat: 0,lng: 179.9},
{lat: 85,lng: 179.9} ];
drawCircle(point, radius, dir) {
let lat;
let lng;
var d2r = Math.PI / 180; // degrees to radians
var r2d = 180 / Math.PI; // radians to degrees
var earthsradius = 3963; // 3963 is the radius of the earth in miles or 6371 in km
var points = 32;
// find the raidus in lat/lon
var rlat = (radius / earthsradius) * r2d;
var rlng = rlat / Math.cos(point.lat() * d2r);
var extp = new Array();
if (dir==1) {var start=0;var end=points+1} // one extra here makes sure we connect the ends
else {var start=points+1;var end=0}
for (var i=start; (dir==1 ? i < end : i > end); i=i+dir) {
var theta = Math.PI * (i / (points/2));
let ey = point.lng() + (rlng * Math.cos(theta)); // center a + radius x * cos(theta)
let ex = point.lat() + (rlat * Math.sin(theta)); // center b + radius y * sin(theta)
extp.push({lat: ey,lng: ex});
}
return extp;
}
Loading the map here
this.map.on(GoogleMapsEvent.MAP_READY).subscribe(() => {
console.log('Map is ready!');
this.geolocation.getCurrentPosition({enableHighAccuracy: true}).then((resp) => {
console.log(resp.coords.latitude);
console.log(resp.coords.longitude);
this.myLat = resp.coords.latitude;
this.myLong = resp.coords.longitude;
let loc: LatLng;
loc = new LatLng (resp.coords.latitude, resp.coords.longitude);
this.map.addPolygon({
'points': this.points,
'strokeColor': "blue",
'holes': this.drawCircle(loc,10,-1), //when adding this I lose the overlay and the hole is not drawn. When I remove it, it starts to work again but without a hole.
'strokeWidth': 4,
'fillColor': "#222222"
});
this.map.moveCamera({
'target': loc,
'zoom': 14
});
this.map.addMarker({
'position': loc,
'title': "Hello GoogleMap for Cordova!",
'icon' : 'https://image.flaticon.com/icons/svg/147/147144.svg'
});
}).catch((error) => {
console.log('Error getting location', error);
});
});
you can make hole by using ctx.clip() function.
1.make a canvas with full width,height.
2.fill canvas with "argb(100,255,0,0)".
3.use arc() and clip() to make a hole.
4.set strokeStyle to "argb(255,255,0,0)".
5.use arc() and stroke() to make red outline.
this is how to make a hole.
I am making hexagon grid for my game based on Google Map v3 and got a problem.
After I click in one hexagon are showing differents values, not one the same as for marker inside of the all hexagon.
The right value is showing just in the left down corner of quarter hexagon.
The value of coord_slug is making based on coordinates lat, lng.
What I have to do hexagon and marker values being the same ?
In this way 55.3,14.8 for upper and 55.25,1485 for down hexagon.
I need those values in a game for downloading dates from database.
The part responsible for displaying the value:
function set_window(event) {
// Set Parameters
var lat = event.latLng.lat();
var lng = event.latLng.lng();
var coord_slug = (Math.round(lat * 20) / 20) + ',' + (Math.round(lng * 20) / 20);
alert(coord_slug);
}
The working part of the script here:
function round_down(n) {
if (n > 0) {
return Math.ceil(n / 0.05) * 0.05;
} else {
return 0;
}
}
var map;
var pointCount = 0;
var locations = [];
var gridWidth = 3660; // hex tile size in meters
var bounds;
var places = [
[55.3, 14.8],
[55.25, 14.85],
]
var SQRT3 = 1.73205080756887729352744634150587236;
$(document).ready(function(){
bounds = new google.maps.LatLngBounds();
map = new google.maps.Map(document.getElementById("map_canvas"), {center: {lat: 55.27, lng: 14.8}, zoom: 10});
// Adding a marker just so we can visualize where the actual data points are.
// In the end, we want to see the hex tile that contain them
places.forEach(function(place, p){
latlng = new google.maps.LatLng({lat: place[0], lng: place[1]});
marker = new google.maps.Marker({
position: latlng,
map: map})
marker.addListener('click', set_window);
// Fitting to bounds so the map is zoomed to the right place
bounds.extend(latlng);
});
// Now, we draw our hexagons! (or try to)
locations = makeBins(places);
locations.forEach(function(place, p){
drawHorizontalHexagon(map, place, gridWidth);
})
});
function drawHorizontalHexagon(map, position, radius){
var coordinates = [];
for(var angle= 0;angle < 360; angle+=60) {
coordinates.push(google.maps.geometry.spherical.computeOffset(position, radius, angle));
}
// Construct the polygon.
var polygon = new google.maps.Polygon({
paths: coordinates,
position: position,
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35,
geodesic: true
});
polygon.setMap(map);
polygon.addListener('click', set_window);
}
// Below is my attempt at porting binner.py to Javascript.
// Source: https://github.com/coryfoo/hexbins/blob/master/hexbin/binner.py
function distance(x1, y1, x2, y2){
console.log(x1, y1, x2, y2);
result = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
console.log("Distance: ", result);
return
}
function nearestCenterPoint(value, scale){
div = value / (scale/2);
console.log("div", div);
mod = value % (scale/2);
console.log("mod", mod);
if(div % 2 == 1){
increment = 1;
} else{
increment = 0;
}
rounded = scale / 2 * (div + increment);
if(div % 2 === 0){
increment = 1;
} else{
increment = 0;
}
rounded_scaled = scale / 2 * (div + increment);
result = [rounded, rounded_scaled]
console.log("nearest centerpoint to", value, result);
return result;
}
function makeBins(data){
bins = [];
data.forEach(function(place, p){
x = place[0];
y = place[1];
console.log("Original location:", x, y);
px_nearest = nearestCenterPoint(x, gridWidth);
py_nearest = nearestCenterPoint(y, gridWidth * SQRT3);
z1 = distance(x, y, px_nearest[0], py_nearest[0]);
z2 = distance(x, y, px_nearest[1], py_nearest[1]);
if(z1 > z2){
bin = new google.maps.LatLng({lat: px_nearest[0], lng: py_nearest[0]});
console.log("Final location:", px_nearest[0], py_nearest[0]);
} else {
bin = new google.maps.LatLng({lat: px_nearest[1], lng: py_nearest[1]});
console.log("Final location:", px_nearest[1], py_nearest[1]);
}
bins.push(bin);
})
return bins;
}
function set_window(event) {
// Set Parameters
var lat = event.latLng.lat();
var lng = event.latLng.lng();
var coord_slug = (Math.round(lat * 20) / 20) + ',' + (Math.round(lng * 20) / 20);
alert(coord_slug);
}
<html>
<head>
<script data-require="jquery#*" data-semver="2.2.0" src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script data-require="bootstrap#*" data-semver="3.3.6" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<link data-require="bootstrap-css#3.3.6" data-semver="3.3.6" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.css" />
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry"></script>
</head>
<body>
<div id="map_canvas" style="width:100%; height:80vh;">
</div>
</body>
</html>
Additional link:
The working part of the script in Plunger
You are setting a position attribute to your Polygons, which seems to be what you want to display...
So you can replace the following
polygon.addListener('click', set_window);
By this:
polygon.addListener('click', function() {
var polyPosition = this.position.lat() + ', ' + this.position.lng();
alert(polyPosition);
});
How do I compute the distance in mile/meters of the displayed Map? Assuming I have the coordinates of the center of the map. I would like to know the distance/radius from the center to the left/right most displayed part of the map? I already got this using Google Map but I'm new in Openlayers. Is there a way to achieve this? Right now my computation in GoogleMap is like this
var bounds = this.instance.getBounds();
var center = bounds.getCenter();
var ne = bounds.getNorthEast();
// r = radius of the earth in statute miles
var r = 3963.0;
var to_radians_divide = 57.2958;
// Convert lat or lng from decimal degrees into radians (divide by 57.2958)
var lat1 = center.lat() / to_radians_divide;
var lon1 = center.lng() / to_radians_divide;
var lat2 = ne.lat() / to_radians_divide;
var lon2 = ne.lng() / to_radians_divide;
// distance = circle radius from center to Northeast corner of bounds
var dis = r * Math.acos(Math.sin(lat1) * Math.sin(lat2) +
Math.cos(lat1) * Math.cos(lat2) * Math.cos(lon2 - lon1));
return dis;
Is there a way to achieve this in OpenLayers? I just want to find out the distance of the left most part of the displayed map from the center
You can achieve this in openlayers also. Here is the code for that and I am using openlayers 3.20.0 version for this example.
var size = map.getSize();
var center = map.getView().getCenter();
var sourceProj = map.getView().getProjection();
var extent = map.getView().calculateExtent(size);
extent = ol.proj.transformExtent(extent, sourceProj, 'EPSG:4326');
var posSW = [extent[0], extent[1]];
var posNE = [extent[2], extent[3]];
center = ol.proj.transform(center, sourceProj, 'EPSG:4326');
var wgs84Sphere = new ol.Sphere(6378137);
var centerToSW = wgs84Sphere.haversineDistance(center, posSW);
var centerToNE = wgs84Sphere.haversineDistance(center, posNE);
console.log("centerToSW - ",centerToSW);
console.log("centerToNE - ",centerToNE);
I am creating a coverage map for my company's vendors, and then need to check how many of our customers live outside the overall coverage. A vendor's coverage area is always a circle.
I used this solution to combine the coverage areas of our vendors into a single polygon so that I can use the containsLocation function to compare out customer's locations. The problem is that the containsLocation function identifies some overlapping coverage areas as being outside coverage. Here is an example, where the pin should remain invisible because it is within the coverage of 2 vendors.
Overlapping Vendor Coverage Example
function updateMap(){
var radius = $('#radius').val();
$.ajax({
url: "",
dataType: "json",
type: "POST",
data: $('#dataForm').serialize()
}).done(function(result){
for(var i=0; i<result.length; i++){
center = {lat: parseFloat(result[i].Latitude), lng: parseFloat(result[i].Longitude)};
shapeArray.push(drawCircle(center, (radius), 1));
}
coverage = new google.maps.Polygon({
paths: shapeArray,
strokeColor: "#ff0000",
strokeOpacity: 0.8,
strokeWeight: 1,
fillColor: "#ff0000",
fillOpacity: 0.35,
map: map
});
});
}
function drawCircle(point, radius, dir)
{
var d2r = Math.PI / 180; // degrees to radians
var r2d = 180 / Math.PI; // radians to degrees
var earthsradius = 3963; // 3963 is the radius of the earth in miles
var points = 32;
// find the raidus in lat/lon
var rlat = (radius / earthsradius) * r2d;
var rlng = rlat / Math.cos(point.lat * d2r);
var extp = new Array();
if (dir==1) {var start=0;var end=points+1} // one extra here makes sure we connect the
else{var start=points+1;var end=0}
for (var i=start; (dir==1 ? i < end : i > end); i=i+dir)
{
var theta = Math.PI * (i / (points/2));
ey = point.lng + (rlng * Math.cos(theta)); // center a + radius x * cos(theta)
ex = point.lat + (rlat * Math.sin(theta)); // center b + radius y * sin(theta)
extp.push(new google.maps.LatLng(ex, ey));
}
return extp;
}
function showUncovered(el){
if(!el.checked){
for(var i=0; i<markerArray.length; i++){
markerArray[i].setVisible(false);
}
return;
}
for(var i=0;i<markerArray.length;i++){
var pos = markerArray[i].position;
var isAffected = false;
if(!google.maps.geometry.poly.containsLocation(pos,coverage)){
markerArray[i].setVisible(true);
}
}
}
Google accepted this as a bug.
https://code.google.com/p/gmaps-api-issues/issues/detail?id=10609
Since you have all the circles you can iterate shapeArray and run .containsLocation(... in each circle, the first that contains the location ends the loop (if not, the marker is outside the polygon).
Actually, this is the solution proposed in the filed bug report (and looks like they won't fix it).