I'm using the (multi-request) reverse geo coding from the HERE-API and request landmarks (in the end I want to find out if a position is above water). Everything works nicely, but I quite often get negative distances to a landmark (especially when the landmark is a river):
{'Distance': -86.3,
'Location': {'Address': {'AdditionalData': [{'key': 'CountryName',
'value': 'United States'},
{'key': 'StateName',
'value': 'New York'}],
'Country': 'USA',
'Label': 'NY, United States',
'State': 'NY'},
'DisplayPosition': {'Latitude': 40.75038, 'Longitude': -73.95749},
'LocationId': 'NT_AkVytIiMG.HuEjq23NLorC',
'LocationType': 'river',
'MapReference': {'CountryId': '21000001',
'PlaceId': '35543547',
'StateId': '21010819'},
'MapView': {'BottomRight': {'Latitude': 40.68625,
'Longitude': -73.79247},
'TopLeft': {'Latitude': 40.8145,
'Longitude': -74.01498}},
'Name': 'East River'},
'MatchLevel': 'landmark',
'MatchQuality': {'Country': 1.0, 'Name': 1.0, 'State': 1.0},
'Relevance': 1.0}
Can someone tell me how I should interpret this distance?
The distance for Reverse Geocoder admin area results is calculated from the supplied point to the
polygon boundary. The distance is therefore negative, where the specified point is inside the area.
This is aligned with landmark results. With gen<6, the distance for admin area results is calculated
from the specified point to the center of the area.
Related
UPDATE 1
I've added the descLength and imageLength properties to allow for easier sorting. The idea is that constant(0) can be used to fill in the values for users who lack either property, and any length greater than 0 can be used to identify a user who actually has the property. The furthest this gets me is being able to order().by() only one property at a time, using a query such as:
g.V().
order().
by(coalesce(values('descLength'), constant(0)))
But this isn't the full solution to match what I need.
Original Post
In amazon neptune I want to sort vertices based on the presence of 2 properties, desc and image. The order of ranking should be:
vertices that have both properties
vertices that have desc but not image
vertices that have image but not desc
vertices that have neither property
Consider this graph of users and their properties:
g.addV('user').property('type','person').as('u1').
addV('user').property('type','person').property('desc', 'second person').property('descLength', 13).as('u2').
addV('user').property('type','person').property('desc', 'third person').property('descLength', 12).property('image', 'https://www.example.com/image-3.jpeg').property('imageLength', 36).as('u3').
addV('user').property('type','person').property('image', 'https://www.example.com/image-4.jpeg').property('imageLength', 36).as('u4')
Using the ranking order I outlined, the results should be:
u3 because it has both desc and image
u2 because it has desc but not image
u4 because it has image but not desc
u1 because it has neither desc nor image
The order().by() samples I've seen work with data like numbers and dates that can be ranked by increasing/decreasing values, but of course strings like urls and text can't. What's the correct way to achieve this?
This first query is not exactly what you are looking for as it treats 'image' and 'desc' as the same weighting, but with this foundation, it should be possible to build out any variations of the query to better meet your needs.
Given:
g.V().hasLabel('user').
project('id','data').
by(id).
by(values('desc','image').fold()).
order().
by(select('data').count(local),desc)
we get
{'id': '92c04ae3-5a7f-ea4c-e74f-e7f79b44ad3a', 'data': ['third person', 'https://www.example.com/image-3.jpeg']}
{'id': 'e8c04ae3-5a7f-2cfb-cc28-cd663bd58ef9', 'data': ['second person']}
{'id': 'c8c04ae3-5a80-5707-8ba6-56554de98f33', 'data': ['https://www.example.com/image-4.jpeg']}
{'id': 'a6c04ae3-5a7e-fd0f-1197-17f3ce44595f', 'data': []}
Building on this, we can go one step further and calculate a score based on how many of the properties exist in each case. The query below gives desc a higher score than image so in the cases where they do not both exist, desc will sort higher.
g.V().hasLabel('user').
project('id','data','score').
by(id).
by(values('desc','image').fold()).
by(union(
has('desc').constant(2),
has('image').constant(1),
constant(0)).
sum()).
order().
by(select('score'),desc)
which yields
{'id': '92c04ae3-5a7f-ea4c-e74f-e7f79b44ad3a', 'data': ['third person', 'https://www.example.com/image-3.jpeg'], 'score': 3}
{'id': 'e8c04ae3-5a7f-2cfb-cc28-cd663bd58ef9', 'data': ['second person'], 'score': 2}
{'id': 'c8c04ae3-5a80-5707-8ba6-56554de98f33', 'data': ['https://www.example.com/image-4.jpeg'], 'score': 1}
{'id': 'a6c04ae3-5a7e-fd0f-1197-17f3ce44595f', 'data': [], 'score': 0}
UPDATED 2022-05-06 To show how to get just the ID
Taking the query above, to get the ID from the results is as simple as adding a select('id') at the end of he query.
g.V().hasLabel('user').
project('id','data','score').
by(id).
by(values('desc','image').fold()).
by(union(
has('desc').constant(2),
has('image').constant(1),
constant(0)).
sum()).
order().
by(select('score'),desc).
select('id')
However, we can also remove some of the other work the query is doing to fetch the results. I mainly included those for demonstration purposes. So we can reduce the query to:
g.V().hasLabel('user').
project('id','score').
by(id).
by(union(
has('desc').constant(2),
has('image').constant(1),
constant(0)).
sum()).
order().
by(select('score'),desc).
select('id')
Is it true that using full country name in free-form text address will gain better "Relevance" scoring as compared to using CountryISO3 code?
In one of the example that I observed.
Case with country iso3 : Flat 1 Church Road, Liverpool, L37 8B,GBR
"Relevance": 0.88,
"MatchLevel": "houseNumber",
"MatchQuality": {
"Country": 1.0,
"City": 1.0,
"Street": [
1.0
],
"HouseNumber": 1.0,
"PostalCode": 0.98
},
Case with full country name : Flat 1 Church Road, Liverpool, L37 8B,united kingdom
"Relevance": 0.91,
"MatchLevel": "houseNumber",
"MatchQuality": {
"Country": 1.0,
"City": 1.0,
"Street": [
1.0
],
"HouseNumber": 1.0,
"PostalCode": 0.98
},
Relevance of the Geocoder API is explained below:
Relevance is a precentage value ranging from 0 to 1 representing the percentage of the input that matches the returned address. "1" means that all input tokens were matched and there was no typo or any other difference.
If the input query contains any additional information – name of the person, phone number or a hint to ring twice – the relevance will be low, but the address returned may be correct.
Low relevance may indicate that the Geocoder API was not able to match some relevant part of the address in the input query.
To separate the above cases one may look at match quality of the fields. These values show how well each of the address elements (e.g. street, city, country etc.) in the results matched to the input that was provided. If all the fields that are important for addressing in the country were matched with high match quality, one can assume that relevance is low because of the additional non-address information. And the result is still highly confident.
https://developer.here.com/documentation/geocoder/dev_guide/topics/scoring.html
I have a 3D model in a coordinate system that is defined in metres. The coordinates have been transformed to have the centre of the bounding box of the model as the origin. A vertex with the coordinates (1, 0, 0) would thus lie 1 metre from the origin.
When trying to add the geometries to the map, with the actual latitude/longitude of the origin as geoPosition, they don't get placed at the exact location and appear smaller than they are. How could I solve this?
Thanks.
You can center the map at whatever point you would like in the world with this method:
map.setCameraGeolocationAndZoom(
//Singapore coordinates and zoom level 16:
new harp.GeoCoordinates(1.278676, 103.850216), 16
);
You can specify the projection type in the MapView's constructor.
To implement a globe projection:
const map = new harp.MapView({
canvas,
theme: "https://unpkg.com/#here/harp-map-theme#latest/resources/berlin_tilezen_base_globe.json",
projection: harp.sphereProjection,
//For tile cache optimization:
maxVisibleDataSourceTiles: 40,
tileCacheSize: 100
});
//And set it to a view where you can see the whole world:
map.setCameraGeolocationAndZoom(new harp.GeoCoordinates(1.278676, 103.850216), 4);
Please refer documentation for more reference:
https://developer.here.com/tutorials/harpgl/#modify-the-map
I am trying to get a polygon shape for a state.
The geocoding api just returns just 2 locations for boundaries, northeast and southwest lat/longs, which are clearly insufficient to get a precise shape.
Eg., for North Carolina, http://maps.googleapis.com/maps/api/geocode/json?address=NC,
below is part of the json response
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : 36.5881568,
"lng" : -75.4599515
},
"southwest" : {
"lat" : 33.840969,
"lng" : -84.32186899999999
}
While i can still form a shape out of this, it will be just a rectangle always. What i am looking for is an api that returns more boundary lat/longs to improve the precision of the shape.
Could you please let me know how to achieve this.
Thanks,
Kiran
The geocoder only returns the bounding box of the polygon (so you can fit the map to show it) not the bounds of the state. To get the bounds of a state you need to have a source for that data. On reasonable free source is the FusionTable containing the NaturalEarth data set:
http://blog.thematicmapping.org/2011/02/natural-earth-vectors-in-cloud.html
Those polygons overlaid on a Google Maps Javascript API v3 map:
http://www.geocodezip.com/geoxml3_test/v3_FusionTables_query_sidebarF_local.html?country=United%20States%20of%20America
The FusionTable containing these polygons is:
Encrypted ID: 19lLpgsKdJRHL2O4fNmJ406ri9JtpIIk8a-AchA
(deprecated numeric id: 420419)
link
I am developing an application using the Google Maps API v3, and I'm struggling to know how to find out if an X coordinate is inside a polygon.
You can use the Geometry Library of the Google Maps JS API. There's a function called containsLocation which tells you if a given LatLng is inside a Polygon. Note that it's a Polygon, not a Polyline. A Polyline is (as it says in the name) a line. So there is no such thing as a point being inside a polyline. You can check if a point is inside a Polygon with the containsLocation function.
google.maps.geometry.poly.containsLocation(somePoint, somePolygon)
In iOS it can be done by using GMSGeometryContainsLocation
Just create a GMSMutablePath, then fill with vertexes of your polygon and test the point.
Example(Swift 4.0):
func isWithin(_ point: CLLocationCoordinate2D) -> Bool {
let p = GMSMutablePath()
p.add(CLLocationCoordinate2D(latitude:30.02356126, longitude: -90.07047824))
p.add(CLLocationCoordinate2D(latitude:30.02501037, longitude: -90.0614231))
p.add(CLLocationCoordinate2D(latitude:30.03321034, longitude: -90.0617981))
p.add(CLLocationCoordinate2D(latitude:30.03192855, longitude: -90.07342815))
return GMSGeometryContainsLocation(point, p, true)
}
Note: If the last param of GMSGeometryContainsLocation is set to true, the GMSMutablePath is composed of great circle segments, otherwise it's of rhumb (loxodromic) segments.