I need to optimize a List of Adresses from my Database using Here Technologies.
The JSON data I am working with looks like this:
Replaced some names and IDs to ensure the Data savety of my client.
"kunde": [
{
"kundenId": ///,
"kundenbezeichnung": "Anger Ernestine",
"kundenNr": "K-///",
"tourHinweis": "",
"nachname": "Anger",
"vorname": "Ernestine",
"strasse": "Bergstraße 18",
"plz": "12169",
"ort": "Berlin",
"telefon1": "030 10449",
"telefon2": "",
"hatLieferAdresse": false,
"schluesselVorhanden": false,
"schluesselInfo": "",
"zahlungsart": "Überweisung",
"bruttoSumme": 1.0000,
"menge": 1,
"tourPos": 0,
"positionen": [
{
"kundenId": ///,
"belposId": ///,
"artikelId": ///,
"menge": 1,
"artikelbezeichnung": "Champigongsauce mit Serviettenknödel",
"artikelNr": "2302457",
"warengruppe": "Diät",
"bestellTypInfo": "Spalte 3",
"bruttopreis": 1.0000
}]},],
´´´
As already mentioned, I need to sort these Adresses to get the optimzed Route. Since my Client has more than 50 Customers per Tour, I cant use the Google Routing API, thats why I am using Here Technologies. The API works perfectly fine, but I don't have the GPS Koordinates stored in the Database. How can I use Here with normal String Adresses?
You can make use of our geocode APIs. In the geocode API you can pass the String address to get the Coordinates. And once you have the Coordinates you can pass in the routing APIs to calculate the route.
Sample HERE geocode endpoint to get the Coordinates of string address.
https://geocode.search.hereapi.com/v1/geocode?q=jammu&apikey=your_api_key
More details of our geocode product are covered in below product document.
https://developer.here.com/documentation/geocoding-search-api/dev_guide/index.html
Related
I'm trying to use HERE Map Attributes API to retrieve the addresses for some map area.
As far as I understood the layer I need is the POINT_ADDRESS layer (check the docs).
The problem is that the layer contains coordinates and identifiers only, but not the structured addresses:
[
{
"ADDRESS_POINT_ID": "334030589",
"LINK_ID": "1286528309",
"SIDE": "R",
"ADDRESSES": "ENGBN682",
"ADDRESS_TYPE": "1",
"BUILDING_NAMES": "ENGBNnull",
"DISPLAY_LAT": "-2751772",
"DISPLAY_LON": "15307500",
"ARRIVAL_LINK_ID": null,
"ARRIVAL_SIDE": null,
"LAT": "-2751797",
"LON": "15307488",
"TOPOLOGY_ID": "215602187",
"START_OFFSET": "8043"
},
...
]
So the question is: how to retrieve the structured address for every point from the POINT_ADDRESS layer? Should I use HERE Batch Geocoder API and perform reverse geocoding for these points? Or it's still possible to achieve that with Map Attributes API only?
On this link https://developer.here.com/documentation/content-map-attributes/dev_guide/topics/here-map-content.html are not all layers in the list.
Please see all layers on https://demo.support.here.com/pde .
In the weu region on https://demo.support.here.com/pde/layers?region=WEU&release=latest&url_root=pde.api.here.com
To retrieve the structured address you need additional layers ROAD_ADMIN_NAMES and ROAD_NAME
Then you request will be like: https://smap.hereapi.com/v8/maps/attributes.json?in=proximity:-27.51772,153.075001;r=100&layers=ROAD_NAME_FCn,ROAD_ADMIN_NAMES_FCn,POINT_ADDRESS&apikey=
Regarding docs on https://developer.here.com/documentation/content-map-attributes/api-reference.html
The parameter 'in' could be: proximity or bbox or corridor - for these in case for big areas you can get limitations due big data. Therefore some times it could be better use in=tile:...
Tile Ids you can get by these formulas:
tile size = 180° / 2^level [degree]
tileY = trunc((latitude + 90°) / tile size)
tileX = trunc((longitude + 180°) / tile size)
tileID = tileY * 2 * (2^level) + tileX
Or you can read this documentation https://demo.support.here.com/pde/indexes?region=WEU&release=latest&url_root=pde.api.here.com
How to get tileid by some index like:
https://smap.hereapi.com/v8/maps/index.json?layer=ROAD_GEOM_FCn&attributes=LINK_ID&values=1286528309,130742823
Then by tile request will be like:
https://smap.hereapi.com/v8/maps/attributes?apikey=&layers=POINT_ADDRESS,ROAD_NAME_FC4,ROAD_NAME_FC5,ROAD_ADMIN_NAMES_FC4,ROAD_ADMIN_NAMES_FC5&in=tile:46594870,11648411,46594870,11648411,46594870
Request: https://reverse.geocoder.api.here.com/6.2/reversegeocode.json?app_id=APP_ID&app_code=APP_CODE&mode=retrieveAreas&prox=35.1377685%2C33.9196697%2C1000&language=en&gen=9
Replace these two by actual values: APP_ID, APP_CODE
This is response:
{
"Response":{
"MetaInfo":{
"Timestamp":"2019-05-06T10:31:19.317+0000"
},
"View":[
{
"_type":"SearchResultsViewType",
"ViewId":0,
"Result":[
{
"Relevance":1.0,
"Distance":-1092.5,
"Direction":149.7,
"MatchLevel":"city",
"MatchQuality":{
"Country":1.0,
"County":1.0,
"City":1.0,
"PostalCode":1.0
},
"Location":{
"LocationId":"NT_iVkNRSYU-2l2WyhtuOg9TB",
"LocationType":"area",
"DisplayPosition":{
"Latitude":35.13116,
"Longitude":33.9244
},
"MapView":{
"TopLeft":{
"Latitude":35.16061,
"Longitude":33.88137
},
"BottomRight":{
"Latitude":35.08291,
"Longitude":33.95569
}
},
"Address":{
"Label":"Karakol, Turkish-Cypriot Administered Area",
"Country":"NCY",
"County":"Famagusta",
"City":"Karakol",
"PostalCode":"99450",
"AdditionalData":[
{
"value":"Turkish-Cypriot Administered Area",
"key":"CountryName"
},
{
"value":"Famagusta",
"key":"CountyName"
}
]
},
"MapReference":{
"ReferenceId":"970895970",
"MapId":"UEAM19108",
"MapVersion":"Q1/2019",
"MapReleaseDate":"2019-04-15",
"SideOfStreet":"neither",
"CountryId":"26569036",
"CountyId":"26569038",
"CityId":"26571374"
}
}
}
]
}
]
}
}
See "Country" field:
"Country":"NCY",
As you can see, country code is NCY. I'm trying to find what country uses that 3-letter code and I can't find it anywhere on the internet.
https://www.worldatlas.com/aatlas/ctycodes.htm
It looks like this is some API issue and it returns wrong country code.
As there is no official answer from HERE, I'll give at least some background info.
NCY is probably a non ISO 3166-1-alpha-3 code that represents Northern Cyprus.
Cyprus is a complicated case, with Greece and Turkey claiming influence. I remember 4 zones modeled, a Greek part, a Turkish part, the UN controlled demilitarized zone in between and a British military base.
You can read more at https://en.wikipedia.org/wiki/Cyprus#Administrative_divisions
I'll go a step further and say this should be filed as a bug, for two reasons.
According to the API Reference, the Address object type is as follow (emphasis mine):
Label Assembled address value for displaying purposes.
Country ISO 3166-alpha-3 country code
[...]
As you noticed, and this is the first reason of why it is a bug, NCY is not a valid ISO 3166-alpha-3 country code
Furthermore, your request does not contain the politicalview query parameter, which allows to deal with disputed territories: for exemple, Crimea would be returned as part of Russia if politicalview=RUS is in the request. If politicalview is not specified, the API assumes the "international view".
However, and this is the second reason, the so-called "Turkish Republic of North Cyprus" is recognized only by Turkey. It does not make sense to return a country code other than CYP, except when politicalview=TUR is specified in the request.
I want to get the shape of a road link (form one node to another node, i.e. between 2 junctions) but I cannot find how to do it.
If I try with
https://pde.api.here.com/1/tile.json?app_id=&app_code=&layer=LINK_ATTRIBUTE_FC1&level=9&tilex=537&tiley=399
there is no shape.
This is to store the shape in my geoserver to later reuse the map. I am not sure this is doable according to the commercial license... So any commercial explanation is also welcome.
Is there a price for this? Is this allowed?
I think the ADAS attribute layer would be more useful for your use case:
https://pde.api.here.com/1/tile.json?&app_id=xxx&app_code=yyy&layer=ADAS_ATTRIB_FC1&level=9&tilex=537&tiley=399
Example out of the response:
[...]
"LINK_ID": "52493206",
"HPX": "89681500,-1400,-8000",
"HPY": "502884700,1900,11200",
"HPZ": "18242,22,138",
"SLOPES": "547,-2,92",
"HEADINGS": "334899",
"CURVATURES": "-116",
"VERTICAL_FLAGS": "0",
"REFNODE_LINKCURVHEADS": "9588455:-110:-25252",
"NREFNODE_LINKCURVHEADS": "1143217772:-111:335789",
"BUA_ROAD": "4",
"BUA_ROAD_VERIFIED": "Y"
}, {
"LINK_ID": "52493207",
"HPX": "89658700,-8700",
"HPY": "502913000,13500",
"HPZ": "18592,167",
"SLOPES": "525,70",
"HEADINGS": "",
"CURVATURES": "",
"VERTICAL_FLAGS": "",
"REFNODE_LINKCURVHEADS": "497590520:-88:-22269",
"NREFNODE_LINKCURVHEADS": "869077244:-83:338527",
"BUA_ROAD": "4",
"BUA_ROAD_VERIFIED": "Y"
},
[...]
Here you can see all available layer and the data they contain:
https://pde.api.here.com/1/doc/layers.json?&app_id=xxx&app_code=yyy
Update: Regarding storing of the data please go through the Terms and Conditions on Here Website. https://legal.here.com/en-gb/terms/here-wego-here-application-and-here-maps-service-terms
You undertake that you will safeguard, protect, and keep your HERE
account confidential and shall not disclose it to any person, or store
the information in any manner, except as required by law.
I am trying to learn how to use map reduce functions with Couchbase. until now i created reports engines based on SQL using Where with multi terms (adding and subtracting terms) and to modify the group part.
I am trying to create this report engine using views.
my problem is how to create a report that enable users to dive in and find more and more data, getting all the way to individual ip stats.
For example. how many clicks where today ? which traffic source ? what did they see? which country ? and etc..
My basic doc for this example look like this:
"1"
{
"date": "2014-01-13 10:00:00",
"ip": "111.222.333.444",
"country": "US",
"source":"1",
}
"2"
{
"date": "2014-01-13 10:00:00",
"ip": "555.222.333.444",
"country": "US",
"source":"1",
}
"3"
{
"date": "2014-01-13 11:00:00",
"ip": "111.888.888.888",
"country": "US",
"source":"2",
}
"4"
{
"date": "2014-01-13 11:00:00",
"ip": "111.777.777.777",
"country": "US",
"source":"1",
}
So i want to allow the user to see at the first screen , how many clicks per day there are at this site.
so i need to count the amount of clicks. simple map/reduce:
MAP:
function (doc, meta) {
emit(dateToArray(doc.date),1);
}
Reduce:
_count
group level 4, group true
will create the sum of clicks per hour.
Now if i want to allow a break down of countries, so i need a dynamic param to change.. from what i am understand it can only by the group level..
so assume i have added this to the emit like this:
emit([dateToArray(doc.date),source],1);
and then grouping level 5 will allow this divide, and using the key too focus on a certein date.. but what if i need to add a county break down? adding this to the emit again?
this seem to be a mess, also if i will want to do a country stats before the source.. is there any smarter way to do this?
Second part...
What if i want to get the first count as follow:
[2014,1,28,10] {ip:"555.222.333.444","111.222.333.444","count":"2"}
i want to see all the ips that are counted for this time...
how should i write my reduce function?
this is my current state that doesnt work..
function(key, values, rereduce) {
var result = {id: 0, count: 0};
for(i=0; i < values.length; i++) {
if(rereduce) {
result.id = result.id + (values[i]).ip +',';
result.count = result.count + values[i].count;
} else {
result.id = values.ip;
result.count = values.length;
}
}
return result;
i didnt get the answer format i was looking for..
i hope this is not to messy and that you could help me with this..
thanks!!
For the first part of your question, I think you are on the right track. That is how you break down views to enable coarse drill down. However, it is important to remember that views are not intended to store your entire documents, nor are they necessarily going to be able to give you a clean cut swatch of data. You probably will need to do fine-filtering within the access layer of your code (using Linq perhaps).
For the second part of your question, a reduce is not the appropriate mechanism to accomplish this. Reduce values have a very finite (and limited) size and will crash the map/reduce engine once they get too big. I suspect you have experimented with that and discovered this for yourself.
The way you worded the question, it seems like you wish to search for all IP addresses that have been counted "X" number of times. This cannot be accomplished directly in Couchbase's map/reduce architecture; however, if you simply want the count for a given IP address, that is something the map/reduce framework has built-in (just use Date + IP as a key).
I have a question to couchdb views / map-reduce.
Lets say, we have a database with hotel-documents like the following:
[{
_id: "1",
name: "Hotel A",
type: "hotel",
stars: 3,
flags: ["family-friendly","green-hotel","sport"],
hotelType: "premium",
food: ["breakfast","lunch"]
}, {
_id: "2",
name: "Hotel B",
type: "hotel",
stars: 5,
flags: ["family-friendly","pet-friendly"],
hotelType: "budget",
food: ["breakfast","lunch","dinner"]
}]
To find all hotels with 3 stars, the following view will fit:
function(doc) {
emit([doc.stars, doc.name]);
}
If I use startkey=[3], everything is fine.
But how is it possible to make a view with multiple filters?
For example - all hotels:
with 3 stars and the flags "family-friendly" and "pet-friendly" and
with hotelType "budget"?
with hotelType "premium" and food "breakfast" or "lunch"?
etc.
Any ideas?
EDIT:
I have now decided to use good old mysql. CouchDB was a nice experience for me, but there are tooo much problems if you need more then the data of one document :(
You can emit a key with a group of values:
emit([[doc.stars,doc.hotelType], doc.name]);
The problem is that this only works if you can order your attributes by importance since they will always get reduced in the same order. Kxepal's solution of using different views is probably the best for your situation.
Source: http://wiki.apache.org/couchdb/Introduction_to_CouchDB_views#Grouping
You need to use different views for that. Each view will handle his own domain with own keys. You may create one-view-for-all-data via multiple emit with different key value, but in perspective it will be hard to maintain.
CouchDB views are one-dimensional. And you are looking for multi-dimensional query:
x = stars
y = flags
z = hotelType
Multi-dimensional queries are not supported unfortunately. For example if you need query geographical location by latitude and longitude, than you'll have to use GeoCouch.