get directions about 50meters out - google-maps-api-3

I have a api3 map that generates the pointer in the correct place for a bed and breakfast using
var orchards = new google.maps.LatLng(52.512565,-2.7595);
I want to add in the "Get directions" and its working ok except that its ending at a slightly different place. The directions are ending at a house about 100meters down the road - not quite where the lat/long for the map are. The postcode for the guest house is SY6 7DQ but the directions end at SY6 7DG
How can I get the directions to end in the right place.
You can see what I mean here : http://www.dev.ee-web.co.uk/orchards/index.php?option=com_content&view=article&id=6&Itemid=106
Here's the function that I am using::
function calcRoute() {
directionsVisible=true;
// alter print text
document.getElementById('printMe').innerHTML = " Print directions";
// remove marker
marker.setMap(null);
var start = document.getElementById("startFrom").value;
var end = "52.512565,-2.7595";
var request = {
origin:start,
destination:end,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
}
});
}
I tried putting the correct postcode into google maps, and numbers produced still point to the wrong place.
I'd really appreciate any help
Thanks

It looks like the directions are very accurate when you specify a LatLng on the road. My guess is the original result was unsatisfactory because the marker is off the road.
Go to this page and click on the road where you want the directions to end and copy the latLng value from the right. Paste into your var end = ... I recommend saving the precision.
https://files.nyu.edu/hc742/public/googlemaps/geocodeUK.html

Related

image.filter is not a function in google earth engine

As a newbie to the google earth engine, I have been trying something (https://code.earthengine.google.com/6f45059a59b75757c88ce2d3869fc9fd) following a NASA tutorial (https://www.youtube.com/watch?v=JFvxudueT_k&ab_channel=NASAVideo). My last line (line 60) shows image.filter is not a function, while the one in the tutorial (line 34) is working. I am not sure what happened and how to sort this out?
//creating a new variable 'image' from the L8 collection data imported
var image = ee.Image (L8_tier1 //the details in the data will represent that the band resolution is 30m
//the details in the data will represent that the band resolution is 30m
//.filterDate ("2019-07-01","2021-10-03") //for a specific date range. maybe good to remove it for the function.
//the details in the data will represent that the band resolution is 30m
//the details in the data will represent that the band resolution is 30m
//.filterDate ("2019-07-01","2021-10-03") //for a specific date range. maybe good to remove it for the function.
.filterBounds (ROI) //for the region of interest we are interested in
//.sort ("COLUD_COVER") //for sorting the data between the range with a cloud cover, the metadata property we are interested in. Other way to do this is using the function below.
//.first() //this will make the image choose the first image with the least amount of cloud cover for the area. Other way to do this is using the function below.
);
//print ("Hague and Rotterdam", image); //printing the image in the console
//console on the right hand side will explain everything from the data
//id will show the image deatils and date of the image, for this case 29th July 2019
//under the properties tab cloud cover can be found, this is the least we can get for this area during this period
// //vizualisation of the data in the map with true color rendering
// var trueColour = {
// bands:["SR_B4","SR_B3","SR_B2"],
// min: 5000,
// max: 12000
// };
// Map.centerObject (ROI, 12); //for the centering the area in the center of the map with required zoom level
// Map.addLayer (image, trueColour, "Hague and Rotterdam"); //for adding the image with the variable of bands we made and naming the image
//Alternate way
//Function to cloud mask from the qa_pixel band of Landsat 8 SR data. In this case bits 3 and 4 are clouds and cloud shadow respectively. This can be different for different image sets.
function maskL8sr(image) {
var cloudsBitMask = 1 << 3; //remember to check this with the source
var cloudshadowBitMask = 1 << 4; //remember to check this with the source
var qa = image.select ('qa_pixel'); //creating the new variable from the band of the source image
var mask = qa.bitwiseAnd(cloudsBitMask).eq(0) //making the cloud equal to zero to mask them out
.and(qa.bitwiseAnd(cloudshadowBitMask).eq(0)); //making the cloud shadow equal to zero to mask them out
return image.updateMask(mask).divide(10000)
.select("SR_B[0-9]*")
.copyProperties(image, ["system:time_start"]);
}
// print ("Hague and Rotterdam", image);// look into the console now. How many images the code have downloaded!!!
//filtering imagery for 2015 to 2021 summer date ranges
//creating joint filter and applying to image collection
var sum21 = ee.Filter.date ('2021-06-01','2021-09-30');
var sum20 = ee.Filter.date ('2020-06-01','2020-09-30');
var sum19 = ee.Filter.date ('2019-06-01','2019-09-30');
var sum18 = ee.Filter.date ('2018-06-01','2018-09-30');
var sum17 = ee.Filter.date ('2017-06-01','2017-09-30');
var sum16 = ee.Filter.date ('2016-06-01','2016-09-30');
var sum15 = ee.Filter.date ('2015-06-01','2015-09-30');
var SumFilter = ee.Filter.or(sum21, sum20, sum19, sum18, sum17, sum16, sum15);
var allsum = image.filter(SumFilter);
Filtering is an operation you can do on ImageCollections, not individual Images, because all filtering does is choose a subset of the images. Then, in your script, you have (with the comments removed):
var image = ee.Image (L8_tier1
.filterBounds (ROI)
);
The result of l8_tier1.filterBounds(ROI) is indeed an ImageCollection. But in this case, you have told the Earth Engine client that it should be treated as an Image, and it believed you. So, then, the last line
var allsum = image.filter(SumFilter);
fails with the error you saw because there is no filter() on ee.Image.
The script will successfully run if you change ee.Image(...) to ee.ImageCollection(...), or even better, remove the cast because it's not necessary — that is,
var image = L8_tier1.filterBounds(ROI);
You should probably also change the name of var image too, since it is confusing to call an ImageCollection by the name image. Naming things accurately helps avoid mistakes, while you are working on the code and also when others try to read it or build on it.

GeoFire - Save item to specific location with radius

I don't have any code to share at this point, but I'm trying to figure out how to solve my issue.. I was hoping some of you might have some advice.
I'm building an app where I get the user's lat/long from geolocation and if they are in an predetermined area with a radius they can post data to the server, but not if they aren't in an area that I specified is allowed.. Here is an image for example:
So in this example, the user could post if they are in the radius of one of the circles but not if they aren't.
I would also have to fetch the data based off of which circle they are in..
What I'm wondering is, how would I specify where these radius' exist and does this scale easily? If I needed to add 10-30 new locations would that be easy to do?
You have the user location from the device and as you have the circles; you have the circle centre with their radius. At time of posting, you check the distance from the user location to the circle centre and enumerate thought the circle locations. if the distance is within the radius, they can post if not, not.
var radius = 100 //example
let canPostLocations = [
CLLocation1,
CLLocation2
]
func isInRange() -> Bool {
for canPost in canPostLocations {
let locationDistance = location.distance(from: canPost)
if (locationDistance < radius) {
return true
}
}
return false
}
use as:
var mayPost = false
var userLocation: CLLocation! = nil
if userLocation != nil {
mayPost = InRange(location: userLocation).isInRange()
}

OpenLayer Popups for markers imported from google spreadsheet

I'm looking for a way to use framecloud type popup with my current setup. Unfortunately all my attempts have either not worked or will only work on the most recently placed maker.
In the course of trying to get it to work I have converted my original script from using Markers to using Vectors to placing the marker points (as I've seen that it's easier to customize vectors than markers.)
Now which ever one I can get to work I'll use, but after working on this for a few days I'm at my wits end and need a helping hand in the right direction.
My points are pulled from a google spreadsheet using tabletop.js. The feature is working how I wish it to, with the markers being placed on their respective layer based on a field I called 'type'.
While I have a feeling that might have been the source of my problem with the Markers type layer, I'm not sure how to fix it.
You can view the coding through these pages
(Links removed due to location change.)
Thanks for all help in advance.
I finally got it to work. For anyone in a similar situation here's my final code for the layers. I did change the names of the layers from what they are originally and blacked out the spreadsheet I used, but the changes should be noticeable.
//
//// Set 'Markers'
//
var iconMarker = {externalGraphic: 'http://www.openlayers.org/dev/img/marker.png', graphicHeight: 21, graphicWidth: 16};
var iconGeo = {externalGraphic: './images/fortress.jpg', graphicHeight: 25, graphicWidth: 25};
var iconAero = {externalGraphic: './images/aeropolae.jpg', graphicHeight: 25, graphicWidth: 25}; // Image is the creation of DriveByArtist: http://drivebyartist.deviantart.com/
var vector1 = new OpenLayers.Layer.Vector("1");
var vector2 = new OpenLayers.Layer.Vector("2");
var vector3 = new OpenLayers.Layer.Vector("3");
// Pulls map info from Spreadsheet
//*
Tabletop.init({
key: 'http://xxxxxxxxxx', //Spreadsheet URL goes here
callback: function(data, tabletop) {
var i,
dataLength = data.length;
for (i=0; i<dataLength; i++) { //following are variables from the spreadsheet
locName = data[i].name;
locLon = data[i].long;
locLat = data[i].lat;
locInfo = data[i].info;
locType = data[i].type; // Contains the following string in the cell, which provides a pre-determined output based on provided information in the spreadsheet: =ARRAYFORMULA("<h2>"&B2:B&"</h2><b>"&G2:G&"</b><br /> "&C2:C&", "&D2:D&"<br />"&E2:E&if(ISTEXT(F2:F),"<br /><a target='_blank' href='"&F2:F&"'>Read More...</a>",""))
locLonLat= new OpenLayers.Geometry.Point(locLon, locLat);
switch(locType)
{
case "Geopolae":
feature = new OpenLayers.Feature.Vector(
locLonLat,
{description:locInfo},
iconGeo);
vector1.addFeatures(feature);
break;
case "POI":
feature = new OpenLayers.Feature.Vector(
locLonLat,
{description:locInfo},
iconMarker);
vector2.addFeatures(feature);
break;
case "Aeropolae":
feature = new OpenLayers.Feature.Vector(
locLonLat,
{description:locInfo},
iconAero);
vector3.addFeatures(feature);
break;
}
}
},
simpleSheet: true
});
map.addLayers([vector1, vector2, vector3]);
map.addControl(new OpenLayers.Control.LayerSwitcher());
//Add a selector control to the vectorLayer with popup functions
var controls = {
selector: new OpenLayers.Control.SelectFeature(Array(vector1, vector2, vector3), { onSelect: createPopup, onUnselect: destroyPopup })
};
function createPopup(feature) {
feature.popup = new OpenLayers.Popup.FramedCloud("pop",
feature.geometry.getBounds().getCenterLonLat(),
null,
'<div class="markerContent">'+feature.attributes.description+'</div>',
null,
true,
function() { controls['selector'].unselectAll(); }
);
feature.popup.autoSize = true;
feature.popup.minSize = new OpenLayers.Size(400,100);
feature.popup.maxSize = new OpenLayers.Size(400,800);
feature.popup.fixedRelativePosition = true;
feature.popup.overflow ="auto";
//feature.popup.closeOnMove = true;
map.addPopup(feature.popup);
}
function destroyPopup(feature) {
feature.popup.destroy();
feature.popup = null;
}
map.addControl(controls['selector']);
controls['selector'].activate();
}

Calculating a nearby street to use on streetview

I am facing an unusual problem where I need to calculate the latlong of a position on a map that has streetview imagery, without knowing the actual position.
I know the end destination of my user, but I need to calculate the latlong of a nearby position (approximately 1km away or less, this should be variable) that has streetview imagery and use that as the start destination.
An example would be that I know I need to go to Times Square, but I want to have a start destination that is about 1km away by road. I then need to verify that there is street view imagery for this co-ordinate before I decide that it's the starting point.
The function below recursively doubles the search distance, (up to a maximum of 10000 meters), until a panorama is found.
Sample code:
// Global vars
var G = google.maps;
var streetViewService = new G.StreetViewService();
function getNearSVP(latlon,maxDist) {
streetViewService.getPanoramaByLocation(latlon, maxDist, function(data, status) {
if (status == google.maps.StreetViewStatus.OK) {
return data.location.latLng;
}
else{
if (maxDist < 10000){
maxDist = maxDist * 2;
return getNearSVP(latlon, maxDist);
}
else {
alert('StreetView is not available within '+maxDist+' meters of this location');
}
}
});
}
Live demo here

OpenLayers: parsed GeoJSON points always display at coords(0 , 0)

this is the first time i use OpenLayers and i don't understand what i'm doing wrong.
I try to display a simple point parsed from GeoJSON. The data seems to be parsed correctly (i checked with the console) but whatever point i give, it always displays at a position i guess to be LonLat(0,0) on my vector layer.
What am i doing wrong ?
var map, baseLayer, placesLayer, geojsonParser ;
// data below have been simplified and reformated to enhance readability
var geojsonData =
{
"type":"Feature",
"geometry":
{
"type":"Point",
"coordinates":[-4.0280599594116,5.3411102294922]
},
"properties":
{
"id":273,
"name":"ABIDJAN"
}
};
$(document).ready(function(){
map = new OpenLayers.Map('map');
baseLayer = new OpenLayers.Layer.OSM();
placesLayer = new OpenLayers.Layer.Vector();
geojsonParser = new OpenLayers.Format.GeoJSON();
placesLayer.addFeatures(geojsonParser.read(geojsonData));
map.addLayers([baseLayer,placesLayer]);
map.setCenter(
new OpenLayers.LonLat(-4, 5.3).transform(
new OpenLayers.Projection("EPSG:4326"),
map.getProjectionObject()
), 5
);
}); // document ready
This is the right solution:
var geojson_format = new OpenLayers.Format.GeoJSON({
'internalProjection': new OpenLayers.Projection("EPSG:900913"),
'externalProjection': new OpenLayers.Projection("EPSG:4326")
});
source: https://gist.github.com/1118357
Hi it sounds like you need to transform the long/lat coordinaites into the correct display coordinates:
You can either declare the projections and then transform your geometry feature:
var projWGS84 = new OpenLayers.Projection("EPSG:4326");
var proj900913 = new OpenLayers.Projection("EPSG:900913");
feature.geometry.transform(projWGS84, proj900913);
Or get the map projection "on the fly" more like this:
var projWGS84 = new OpenLayers.Projection("EPSG:4326");
feature.geometry.transform(projWGS84, map.getProjectionObject());
Obviously if you are using a different input projection from me change "ESPG:4326" to whatever you require.
HTH
C
EDIT:
In your case you would need to write something like:
geojsonData.geometry.transform(projWGS84, map.getProjectionObject());

Resources