Grouped nodes in OpenStreetMap with Overpass API - openstreetmap

Hy.I would like to query nodes gruped by some area. For example: how to get all nodes (e.g. peaks) for given area (eg. administrative boundary - country).
Something like join in SQL:
SELECT n.*, a.name from node n LEFT JOIN area a ON n.area_id = a.id WHERE n.type = "peak"
Resoult would be something like:
{ features: [
{
type: "node:",
area: "slovenia"
properties: {....},
geometry: {...}
},
...
]}
or maybe:
{ areas: [
slovenia: {
nodes: [
{
type: "node:",
area: "slovenia"
properties: {...},
geometry: {...}
},
...
]
},
...
]}
Is this even possible? Or should I first make 1 query for all areas and then for each area make another query?

Area in area support is not yet officially available (see this Github pull request for some ideas how this might look like in the future), but you could use the approach described on the following help page:
https://help.openstreetmap.org/questions/35976/add-reverse-geocoding-information-to-the-overpass-resulting-set
In particular I'd recommend to take a look at the following query: http://overpass-turbo.eu/s/4FJ
It works with a single query but mixes sign posts with all areas this sign post is included.You should be able to easily adjust this to your tags / area. Note that a bit of post processing on the result may be required.
Probably the closest thing you're looking for is also described in the Github pull request. This would print the area followed by all nodes in that area. But as I mentioned, this will only be available at some point in the future.
Sample output:
#oname #id name
area 3600062387 Landkreis Merzig-Wadern
node 313138635
node 313150002
node 313460474
node 315050154
node 431311279
...

Related

Creating a custom refinementList component based on two facets - Algolia

Let’s suppose we have these two facets:
“manufacturer.url”: [“/url1”, “/url2”, “/url3”]
AND
“manufacturer.name”: [“manufacturer1”, “manufacturer2”, “manufacturer3”];
I’d like to create a custom refinmentList component which show all available facets for my hits based on manufacturers.
I used connectRefinementList(MyCustomComponent); and I set manufactuer.url to attribute property.
<CustomManufacturerFilterRefinementList
attribute="manufacturer.url"
currentCategory={currentCategory}
limit={10}
locale={locale}
showMore={showMore}
searchable={searchable}
showMoreLimit={showMoreLimit}
translations={translations}
/>
Now users can see available manufacturers and can filter them or click on them to go to the manufacturer page, but since I fetch the manufacturer.url, I could only able to show the URL in the list, but I’d like to show manufacture’s name in the list and having URL to generate links.
Problem: how can I create a custom refinementList component which fetches data from two facets at the same time and combine them to generate a list of links?
PS: I tried to use searchForFacetValues function inside my custom component to retrvie manufacturer’s name with below query but I couldn’t map each url with name because there is no logical relation between them:
{
"requests": [
{
"indexName": "stg_lots",
"params": {
"facetName": [
"manufacturer.name"
],
"filters": "manufacturer.url:\"froemag\" OR manufacturer.url:\"volvo\" OR manufacturer.url:\"fendt\" ",
"maxFacetHits": 100
}
}
]
}
Thanks

AG Grid Row-Grouping for showing version history of data

I'm a first time user of AG Grid and need some help identifying how to configure Row Grouping for my AG Grid in such a way that allows me to see my data group as a timeline/audit history. Was reading through the docs and haven't found an example on there that resembles what I'm looking for.
I have rowData that contains history and the visual expectation is that, the same base columnDefs assigned to the grid are used for the main "group" row (that contains the expand/collapse chevron) and all the expanded rows as well -- so there is no need for a "group column"
Anyone know how I can achieve this outcome? I have also looked at treeData and masterDetail but those didn't work out for me.
P.S. I don't rule out the possibility that I could be misreading/misunderstanding the AG Grid docs so any help there is appreciated.
EDIT: After fiddling around with things further, I believe I'm looking for a combination of two things:
The isRowMaster to enable expand/collapse on the main parent entry.
The groupDisplayType="groupRows" setting (minus the default row group cell because that would be handled by my master row from Point 1 instead)
After much head banging, turns out the solution was to use treeData. What I ended up creating was treeData containing only one level children.
Parent Node (expand/collapse)
child 1
...
child n
The other key was understanding how to structure your rowData and returning the proper dataPath to feed into the getDataPath handler for treeData. AG Grid expects a flat-list for rowData -- I say this as I was not able to get things working when having a nested tree structure like the following.
const mainRecord = {
id: "abc"
foo: 1,
bar: 2,
history: [
{ foo: 3, bar: 4 },
{ foo: 5, bar: 6 }
]
}
I had to modify my data structure above to return the history items as a flat list alongside the main record that I eventually sent as rowData. The other thing I had to do was add some hierarchy property to my objects to denote its placement in the tree. The hierarchy value is what I supplied to getDataPath
const rowData = [
{ id: "abc", foo: 1, bar: 2, hierarchy: ["abc"] }, // parent
{ foo: 3, bar: 4, hierarchy: ["abc", "34"] }, // child 1
{ foo: 5, bar: 6, hierarchy: ["abc", "56"] }, // child 2
]
After doing the above changes, I was able to get the expected visual outcome I was looking for. I think the big takeaway I got from this is as a first time user of AG Grid is, let it take care of grouping of your data on your behalf (as opposed to doing it yourself via structuring your models with some internal nested children structure)

Omit response fields on Bing maps query

I'm looking for ways to reduce my bing maps query response size. For example - If I'm interested in the road distance between Seattle and LA, I'd query:
http://dev.virtualearth.net/REST/V1/Routes?wp.0=seattle&wp.1=losangeles&key=
(sorry, you'll have to use your own key)
... and that would give me something this (~1kB):
{
...
[
{
estimatedTotal: 1,
resources:
[
{
__type: "Route:http://schemas.microsoft.com/search/local/ws/rest/v1",
bbox:
[
34.053493,
-123.393781,
47.604151,
-118.242588
],
id: "v65,h-1259215200,i0,a0,cen-US,dAAAAAAAAAAA1,y0,s1,m1,o1,t4,w5D47BElTIPU1~ArgmUSjRxBABAADgAVva_j4A0~U2VhdHRsZSwgV0E1~~~,w9ecGAxFDffU1~ArgmUSgxwaIFAADgAQw_AT8A0~TG9zIEFuZ2VsZXMsIENB0~~~,k1",
distanceUnit: "Kilometer",
durationUnit: "Second",
routeLegs:
[],
travelDistance: 1827.815,
travelDuration: 58573,
travelDurationTraffic: 60478
}
]
}
],
...
This would look good, except expanding the routeLegs node gives me another ~23kB of data in the response - the full route - which I don't need. Anyone knows a way how to filter this out (either routeLegs or any of the underlying nodes?)
Thanks
You can now use the routeAttributes parameter documented here: https://msdn.microsoft.com/en-us/library/ff701717.aspx

MongoDB Social Network Adding Followers

I'm implementing a social network in MongoDB and I need to keep track of Followers and Following for each User. When I search for Users I want to display a list like Facebook with the User Name, Picture and number of Followers & Following. If I just wanted to display the User Name and Picture (info that doesn't change) it would be easy, but I also need to display the number of Followers & Following (which changes fairly regularly).
My current strategy is to embed the People a User follows into each User Document:
firstName: "Joe",
lastName: "Bloggs",
follows: [
{
_id: ObjectId("520534b81c9aac710d000002"),
profilePictureUrl: "https://pipt.s3.amazonaws.com/users/xxx.jpg",
name: "Mark Rogers",
},
{
_id: ObjectId("51f26293a5c5ea4331cb786a"),
name: "The Palace Bar",
profilePictureUrl: "https://s3-eu-west-1.amazonaws.com/businesses/xxx.jpg",
}
]
The question is - What is the best strategy to keep track of the number of Followers & Following for each User?
If I include the number of Follows / Following as part of the embedded document i.e.
follows: [
{
_id: ObjectId("520534b81c9aac710d000002"),
profilePictureUrl: "https://pipt.s3.amazonaws.com/users/xxx.jpg",
name: "Mark Rogers",
**followers: 10,**
**following: 400**
}
then every time a User follows someone requires multiple updates across all the embedded documents.
Since the consistency of this data isn't really important (i.e. Showing someone I have 10 instead of 11 followers isn't the end of the world), I can queue this update. Is this approach ok or can anyone suggest a better approach ?
You're on the right track. Think about which calculation is performed more - determining the number of followers/following or changing number of followers/following? Even if you're caching the output of the # of followers/following calculation it's still going to be performed one or two orders of magnitude more often than changing the number.
Also, think about the opposite. If you really need to display the number of followers/following for each of those users, you'll have to then do an aggregate on each load (or cache it somewhere, but you're still doing a lot of calcs).
Option 1: Cache the number of followers/following in the embedded document.
Upsides: Can display stats in O(1) time
Downsides: Requires O(N) time to follow/unfollow
Option 2: Count the number of followers/following on each page view (or cache invalidation)
Upsides: Can follow/unfollow in O(1) time
Downsides: Requires O(N) time to display
Add in the fact that follower/following stats can be eventually consistent whereas the counts have to be displayed on demand and I think it's a pretty easy decision to cache it.
I've gone ahead and implement the update followers/following based on the same strategy recommended by Mason (Option 1). Here's my code in NodeJs and Mongoose and using the AsyncJs Waterfall pattern in case anyone is interested or has any opinions. I haven't implemented queuing yet but the plan would be to farm most of this of to a queue.
async.waterfall([
function (callback) {
/** find & update the person we are following */
Model.User
.findByIdAndUpdate(id,{$inc:{followers:1}},{upsert:true,select:{fullName:1,profilePictureUrl:1,address:1,following:1,followers:1}})
.lean()
.exec(callback);
},
function (followee, callback) {
/** find & update the person doing the following */
var query = {
$inc:{following:1},
$addToSet: { follows: followee}
}
Model.User
.findByIdAndUpdate(credentials.username,query,{upsert:true,select:{fullName:1,profilePictureUrl:1,address:1,following:1,followers:1}})
.lean()
.exec(function(err,follower){
callback(err,follower,followee);
});
},
function(follower,followee,callback){
/** update the following count */
Model.User
.update({'follows._id':follower.id},{'follows.$.following':follower.following},{upsert:true,multi:true},function(err){
callback(err,followee);
});
},
function(followee,callback){
/** update the followers count */
Model.User
.update({'follows._id':followee.id},{'follows.$.followers':followee.followers},{upsert:true,multi:true},callback);
}
], function (err) {
if (err)
next(err);
else {
res.send(HTTPStatus.OK);
next();
}
});

Does it make sense to use internal anchors for filtering a REST API's representation?

As a follow up to my previous question about REST URIs for retrieving statistical information for a web forum Resource, I want to know if it is possible to use the internal anchors as filter hints. See example below:
a) Get all statistics:
GET /group/5t7yu8i9io0op/stat
{
group_id: "5t7yu8i9io0op",
top_ranking_users: {
[ { user: "george", posts: 789, rank: 1 },
{ user: "joel", posts: 560, rank: 2 } ...]
},
popular_topics: {
[ ... ]
},
new_topics: {
[ ... ]
}
}
b) GET only popular topics
GET /group/5t7yu8i9io0op/stat#popular_topics
{
group_id: "5t7yu8i9io0op",
popular_topics: {
[ ... ]
}
}
c) GET only top ranking users
GET /group/5t7yu8i9io0op/stat#top_ranking_users
{
group_id: "5t7yu8i9io0op",
top_ranking_users: {
[ { user: "george", posts: 789, rank: 1 },
{ user: "joel", posts: 560, rank: 2 } ...]
}
}
Or should I be using query parameters ?
Not sure what you are trying to do exactly, but make sure you understand that fragment identifiers are not seen by the server, they are chopped off by the client connector.
See: http://www.nordsc.com/blog/?p=17
I've never seen anchors being used that way - it's interesting. That being said, I'd suggest using query parameters for a couple of reasons:
They're standard - and consumers of your api will be comfortable with them. There's nothing more annoying that dealing with a quirky api.
Many frameworks will auto-parse the query parameters and set them in a dictionary on the request object (or whatever analogue exists in your framework / http server library).
I think it would make more sense to have:
/group/5t7yu8i9io0op/stat/top_users
/group/5t7yu8i9io0op/stat/popular_topics
/group/5t7yu8i9io0op/stat/new_topics
/group/5t7yu8i9io0op/stat/user/george
No you cannot do that because as Jan points out the server will never see that fragment identifier. Literally, that part of the url will not reach the server.