I have a specific problem, and I find it hard to find a solution!
Using a GPS Device I can find my current position on earth. I need to be able to point to a direction (a compass on iPhone or similar device) and find what important objects (locations) are in that direction! Assume that I do have all those locations stored in a database.
Assuming you have a location and a direction, your goal is to find what items in your database are adjacent to the location, in the appropriate direction.
Obviously, you could scan through every element in your database, and answer for each one, "Is this in the region?". The real magic is efficiency; how you index the data in the database such that you can answer that question without having to examine every record.
A great example of this is in MongoDB. However it's implementation does not handle direction, so you will need to filter the results. You will use the database to get all objects within x distance of you, and will filter out those elements which are not in the appropriate direction.
If you cannot use a database engine with native geospatial indexing, you'll have to implement it yourself. As mentioned in the comments, the Haversine function is used to compute distance on a sphere (in this case, the earth). Rather than computing the distance between every point and yourself, you could begin by eliminating any elements which are grossly out of range, e.g. (your latitude + your search distance) < (the objects latitude). Then use the Haversine to filter further. You could also use a geospatial hashing function to do most of the work beforehand.
Once you have all of the elements within range, you can convert the x-y coordinates in your database into the polar coordinates. In short:
arctan((item_y - users_y) / (item_x - users_x)) = the angle between the item and the user
If you compute this for every item within 'range' of the user, and filter out any elements which are not within some bounds of the compass angle (+/- 20 degrees, for example), you will get the elements you need.
If efficiency is still an issue, you can get more clever by immediately invalidating any elements which, for example are on the wrong side of the user (if the user is facing west, than any elements which have an x coordinate higher than the user cannot possibly be in his view). Depending on your programming language, it may also be more efficient to use a static table of arctans with a lower degree of accuracy than is commonly provided.
If you are particularly clever, you may also find ways of indexing the data by angle, which will further lower the computation required.
Related
I have got a collection of documents with two fields: a location (Geopoint) and a distance (Number).
The user input is another location (Geopoint).
I've to return all the documents where the distance between the location of the document and the location of the input is less than the distance of the document.
This tutorial shows how to perform nearby location queries but how can I insert in the equation the distance if it is not given by the user but different for each document?
I came up with a solution.
Instead of saving a geopoint and a radius (representing a circle), I can store the circumscribed square, so I will store two longitudes (geopoint longitude + and - radius) and two latitudes (geopoint latitude + and - radius).
Then I can do a compound query of 4 parts to see if the user geopoint is in the square.
Anyway, this is an imperfect solution because there is a lack of precision in the circle/square approximation, but in my specific case, it doesn't matter. Therefore if in your case precision matters you can save radius (or calculate from square wide), and then make a filter on the objects you queried.
Generalizing, this method can be easily applied to any polygon:
Save in the firestore document the polygon coordinates and the circumscribed rectangle.
Query the documents in Firestore using the four rectangle coordinates
Filter results using the original polygons.
You'll need to calculate the bounding box for your query, based on the position the user entered, and the maximum distance you want to return results for. When using geohashes (as the tutorial does), you'll actually need to calculate four bounding boxes: one in each quadrant from the center of the results that the user entered.
If you've never done this, it can be a bit hard to do it yourself, which is probably why the tutorial author doesn't cover it. But there are multiple Geo-libraries for Firestore which do this for you, and I'd highly recommend checking them out.
If you'd like to learn more about how the whole searching process works, I recommend checking out the video of my talk a while ago: Querying Firebase and Firestore based on geographic location or distance.
I need help writing a resilient, mapping (graph building) algorithm. Here is the problem:
Imagine you have a text oriented virtual reality(TORG/MUD) where you can send movement commands (n, s, w, e, up, down, in, out ... etc.) through telnet to move your character from room to room. And the server sends back corresponding room description after each movement step. Your task is to generate a graph that represents the underlying map structure, so that you can simply do a DFS on the client side to figure out how to get from one room to another. Also you want to design the system so that minimum user input is required
Here are the assumptions:
The underlying graph topology on the server never change.
Room descriptions are not unique. Most of the rooms have distinct descriptions, but some of the rooms have the exact same description. Room description are changed slightly once in a while(days or weeks)
Your movement may fail randomly with a small probability, and you will get an error message instead of the new room description, such as "You stop to wait for the wagon to pass", "The door is locked", and your character will still be in the current room.
You cannot assume the unit spacial distance for each movement. For example you may have a topology like the one shown below, so assuming unit distance for each neighboring room and assigning a hard coordinate to each room is not going to work. However you may assume that the relative direction to be consistent, that is there will be no loop in a topological sort along X(west, east) and Y(south, north).
Objective: given a destination that you have visited before, the algorithm guarantees to eventually move you to that location, and will find the shortest path most of the time. Mistakes are allowed, but the algorithm should be able to detect and correct the mistakes on the fly.
Example graph:
A--B---B
| | <- k
C--D-E-F
I have already implemented a very simple solution that would record the room descriptions and construct a graph. The following is an example of a graph representation my program generates in json. The "exits" are movement direction mapped to node id. -1 represents an un-mapped room. If the user walks in a direction and detect a -1 in the graph representation, the algorithm will attempt to find nodes already in the graph. If nodes with the same description are found, it will prompt the user to decide whether the newly seen room is one of the old nodes. If not, it adds a new node and connect it to the graph.
"node": [
{
"description": "You are standing in the heart of the Example city. There is a fountain with large marble statue in it...",
"exits": {
"east": -1,
"north": 31,
"south": 574,
"west": 42
},
"id": 0,
"name": "cot",
"tags": [],
"title": "Center of Town",
"title_color": "\u001b[1m\u001b[36m Center of Town\u001b[0;37;40m"
},
{
...
This simple solution requires human input detect loops when building the graph. For example, in the graph shown above, assume same letters represent same room descriptions. If you start mapping at the first B, and to left, down, right...till you perform movement k, now you see B again, but mapper cannot determine whether it is the B it has seen before.
In short I want to be able to write a resilient graph building algorithm that takes a walk (possibly infinite) in a hidden target graph and generate(and keep updating) a graph that can (hopefully) as similar as the target graph. We then use the generated graph to help navigate in the target graph. Is there an existing algorithm for this category of problems?
I also thought about applying some machine learning techniques to this problem, but I am unable to write out a concrete model. I am thinking along the lines of defining a list of features for each room we see (room description, exits, neighboring nodes), and each time we see a room we attempt to find the graph node that best fit the features, and based on some update rule(like Winnow or Perceptron) update the description we see based on some mistakes detection metrics.
Any thoughts/suggestions would be very much appreciated!
Many MU*s will give you a way to get a unique identifier for rooms. (On MUSH and its offshoots, that’s think %L.) Others might be set up to describe rooms you’ve already been to in an abbreviated form. If not, you need some way to determine whether you have been in a room before. A simple way would be to compute a hash of enough information about each room to get a unique key. However, a maze might be deliberately set up to trick you into thinking you’re in a different location. Wizardry in particular was designed to make old-school players mapping the dungeon ny hand tear their hair out when they realized their map had to be wrong, and the Zork series had a puzzle where objects you dropped to mark your place in the maze would get moved around while you were elsewhere. In practice, coding your tool to solve these puzzles is unlikely to be worth it.
You should be able to memoize a table of all-pairs-shortest-paths and update it to match the subgraph you’ve explored whenever you search a new exit. This could be implemented as a N×N table where row i, column j tells you the next step on the shortest path from location i to location j. Normally, for a directed graph. Even running Dijkstra’s algorithm each time should suffice, but in practice each move adds one room to the map and doesn’t add a shorter path between many other rooms. You would want to automatically map connections between rooms you’ve already been too (unless they’re supposed to be hidden) and not force the explorer to tediously walk through each individual exit and back to see where it goes.
If you can design the map, you can also lay out the areas so that they’re easy to navigate between, and then you can keep your tables small: each only needs to contain maps of individual areas you’ve deliberately laid out as mazes to explore. That is, if you want to go from one dungeon to another, you just need to look up the nearest exit, and then directions between the dungeons on the world map, not one huge table that grows quadratically with the number of locations in the entire game. For example, if you’ve laid out the world as a nested hierarchy where a room is in a building on a street in a neighborhood of a city in a region of a country on a continent on a planet, you can just store locations as a tree, and navigating from one area to the others is just a matter of walking up the tree until you reach a branch on the path to your destination.
I’m not sure how machine learning with neural networks or such would be helpful here; if the kind of trick you’re looking out for is the possibility that a room that appears to be the same as one you’ve seen before is really a duplicate, the way to handle that would be to maintain multiple possible maps at once on the assumption that apparently-identical rooms are or are not duplicates, a garden of forked paths.
I need to be able to count all the houses/addresses that exist inside a polygon. I've thought it through and it seems possible to find if a single address exists inside a polygon (by finding if the geolocation intersects with it?)
Is it possible to pull a list of all the addresses in an area and check if they intersect? Or might there be some other method?
If I were to try to do this on the browser client, I would get an array of OpenLayers.LonLat objects or OpenLayers.Geometry.Point objects. I would iterate over that array and ask if each object was within a polygon by calling the containsPoint function of OpenLayers.Geometry.Polygon. I would count or collect the points that fall within the polygon.
Geospatial operations like you are describing are something we do on the server using open source GeoTools. We tend to use OpenLayers almost exclusively for map visualization.
I may have not answered your question entirely because I sense you are trying to get that list of addresses/points in the first place for an area on the map, and I don't think you've provided enough information to answer that part of the question.
I have devices moving across the entire country that report their GPS positions back to me. What i would like to do is to have a system that maps these coordinates to a named area.
I see two approaches to this:
Have a database that defines areas as polygons stretching between various GPS coords.
Use some form of webservice that can provide the info for me.
Either will be fine. It doesn't have to be very accurate at all, as i only need to know the region involved so that i know which regional office to call if something wrong happens with the device.
In the first approach, how would you build an SQL table that contained the data? And what would be your approach for matching a GPS coordinate to one of the defined areas? There wouldn't be many areas to define, and they'd be quite large, so manually inputting the values defining the areas wouldn't be a problem.
In the case of the second approach, does anyone know a way of programatically pulling this info off the web on demand? (I'd probably go for Perl WWW::Mechanize in this case). "close to Somecity" would be enough.
-
PS: This is not a "do the work for me" kind of question, but more of a brainstorming request. pseudo-code is fine. General theorizing on the subject is also fine.
In the first approach, how would you build an SQL table that contained
the data? And what would be your approach for matching a GPS
coordinate to one of the defined areas?
Asume: An area is defined as an closed polygon.
You match the GPS coordinate by simply calling a point inside polygon method, like
boolean isInside = polygon.contains(latitude, longitude);
If you have few polygons you can do a brute force search through all existing polygons.
If you have many of them and each (ten-) thousands of points, the you want to use a spatial grid, like a quadtree or k-d tree, to reduce the search to the relevant polygons.
method.
this process is called reverse geocoding, many services providers such as google, yahoo, and esri provide services that will allow to do this thing
they will return the closest point of interest or address, but you can keep the administrative level you are interested in
check terms of use to see which service is compatible with your intended usage
I have been looking for "MapReduce implementation of Shortest path search algorithms".
However, all the instances I could find "computed the shortest distance form node x to y", and none actually output the "actual shortest path like x-a-b-c-y".
As for what am I trying to achieve is that I have graphs with hundreds of 1000s of nodes and I need to perform frequent pattern analysis on shortest paths among the various nodes. This is for a research project I am working on.
It would be a great help if some one could point me to some implementation (if it exists) or give some pointers as to how to hack the existing SSSP implementations to generate the paths along with the distances.
Basically these implementations work with some kind of messaging. So messages are send to HDFS between map and reduce stage.
In the reducer they are grouped and filtered by distance, the lowest distance wins. When the distance is updated in this case, you have to set the vertex (well, some ID probably) where the message came from.
So you have additional space requirement per vertex, but you can reconstruct every possible shortest path in the graph.
Based on your comment:
yes probably
I will need to write another class of the vertex object to hold this
additional information. Thanks for the tip, though it would be very
helpful if you could point out where and when I can capture this
information of where the minimum weight came from, anything from your blog maybe :-)
Yea, could be a quite cool theme, also for Apache Hama. Most of the implementations are just considering the costs not the real path. In your case (from the blog you've linked above) you will have to extract a vertex class which actually holds the adjacent vertices as LongWritable (maybe a list instead of this split on the text object) and simply add a parent or source id as field (of course also LongWritable).
You will set this when propagating in the mapper, that is the for loop that is looping over the adjacent vertices of the current key node.
In the reducer you will update the lowest somewhere while iterating over the grouped values, there you will have to set the source vertex in the key vertex by the vertex that updated to the minimum.
You can actually get some of the vertices classes here from my blog:
Source
or directly from the repository:
Source
Maybe it helps you, it is quite unmaintained so please come back to me if you have a specific question.
Here is the same algorithm in BSP with Apache Hama:
https://github.com/thomasjungblut/tjungblut-graph/blob/master/src/de/jungblut/graph/bsp/SSSP.java