WithinDistance in spatial indexing neo4j not give appropriate Result - neo4j

We are using Spring Data Neo4j 3.2.0 ,and Neo4j-spatial 0.13-neo4j-2.1.6 in a Grails Project 2.4.3
In UserDomain
#Indexed(indexType = IndexType.POINT, indexName = "junctionLocations")
Point wkt
In UserRepository
#Transactional
Result<UserDomain> findWithinDistance( final String indexName, Circle circle)
#Query("START item=node:junctionLocations({0}) RETURN labels(item) as label ,item")
List match(String a)
So when we run
Iterable<UserDomain> teamMembers1 = userDomainRepository.findWithinDistance
("junctionLocations", new
Circle(new Point(28.6100,77.2300),new Distance(2, Metrics.KILOMETERS)));
Then it give exact data
but when we run
Iterable<UserDomain> teamMembers = userDomainRepository.match("withinDistance:[28.6100,77.2300,2.0]")
then it does not give any data but if we increase the distance to 10000 then it give data .
Actually we want to get correct data using Cypher Query.
Are we missing something ?
Is there anyway to get correct data using Cypher ?

I think there is some problem in Documentation of Spatial Repository
#Transactional
Result<T> findWithinDistance(final String indexName, final double lat, double lon, double distanceKm);
. In database we have corrdinates of Delhi and Gurgaon
Delhi Latitude : 28.38
Longitude : 77.12
Gurgaon Latitude : 30.30
Longitude : 74.60
So from my point of view , If I search
findWithinDistance("junctionLocations", 28.6100,77.2300, 35.5);
i.e 28.6100 lat and 77.23 long and 35.5 Distance in km
this does not give any data
But if I swap lat,lon position then Query give appropriate result
findWithinDistance("junctionLocations",77.2300, 28.6100, 35.5);
So If I am correct then in Spatial Repository correct way is
#Transactional
Result<T> findWithinDistance(final String indexName, final double lon, double lat, double distanceKm);

Related

how to extract twitts with special location and also special subject

please let me know if I am unclear,
I am extracting twits using Twitter API
my final goal is to extract twits in Chicago, also with the subject of pizza,
I mean finding all the twitts that are about pizza, and also the user location is in chicago,
I would have gotten two approaches:
I tried the first approaach:
applying geolocation in my search,
there is a problem with that, it seems it can't apply both the filters(chicago, pizza) with each other.
this is one screen shot of the result:
maybe because users don't say about their locations when they are twiting, so it can't be applied I am not sure.
this is the code I am using:
FilterQuery fq = new FilterQuery();
String keywords[] = {"pizza"};
double lat = 41.793474;
double lon = 87.984886;
double lon1 = lon - .5;
double lon2 = lon + .5;
double lat1 = lat - .5;
double lat2 = lat + .5;
double box[][] = {{lon1, lat1}, {lon2, lat2}};
fq.locations(box);
fq.track(keywords);
twitterStream.addListener(listener);
twitterStream.filter(fq);
2. the another approach and the better one is to extract the location of the user and use that for filtering.
I have no idea of how to apply this to my code.
so I have two questions:
what is wrong with the first approach I am using(do you think its because the user does not say about her or his location)?
if the first approach can't be applied for my case, how I can mix the second approach? I mean how I can extract the location of the user from their profile then apply that to the filter.
many thanks for taking the time :)
When you stream and track both a word and a location, the two filters are OR'ed. You want them to be AND'ed. In other words, you will get results that match either filter. The best approach is to filter only for location. Then, write your own code that finds tweets in those results that match your word filter.
Another problem you will face is that very few users opt to include location information.

How do I use spring-data-neo4j with spatial indexes and cypher?

I want to use a spatial index in Neo4j with the spring-data-neo4j framework. Additionally I want to query the index using cypher. The database is embedded.
I'm a bit clueless as to how to get it to all wire together.
With a domain object like this,
#NodeEntity
class Junction {
#GraphId Long id;
#Indexed(indexType = IndexType.POINT, indexName = "junctionLocations") Point wkt;
}
SDN ought to be maintaining the index for me. It appears so, as I can do spatial queries using the repository:
interface JunctionGraph extends GraphRepository<Junction>, SpatialRepository<Junction> {}
with
junctionGraph.findWithinBoundingBox("junctionLocations", new Box(lowerBound.point, upperBound.point))
However, I understand that to query this index using cypher (via a #Query in the repository) this spatial index configuration won't work. I think that this is because each node needs to be manually added to the spatial index (or at least a proxy for the node). That means that adding this to JunctionGraph:
#Query("START n=node:junctionLocations('withinDistance:[{0}, {1}, {2}]') MATCH n-[*]->(i:Item) return i")
Collection<Item> getItemsWithin(double lat, double lon, double radius)
doesn't work.
Does anyone have a working recipe? It appears to be a bit black magic to me, and I'm unsure what the best way to proceed within SDN is.
It works, you just have to create the whole query string outside and pass it as parameter, placeholders within string constants are not substituted.
#Query("START n=node:junctionLocations({0}) MATCH n-[*]->(i:Item) return i")
Collection<Item> getItemsWithin(String query)
you have to do the replacement yourself, .e.g. using String.format
String.format("withinDistance:[%f, %f, %f]",lat,lon,radius)

Putting random latitude and longitude in google maps geolocation?

I have latitude and longitude of some cities and I want to input it the geocoder randomly. Can anyone please tell me how do I do that. The values are both negative and float. for an instance mexico lat/long 23.634501,-102.552784
myLatlng = new google.maps.LatLng(1.352083,103.819836);
I want to put values randomly from a set of values in Latlng function. Thanks
You don't specify your programming language, so I'll answer language agnostic.
I'll assume you have a Point type that can take two double values, e.g.
class Point
{
double Latitude;
double Longitude;
}
and that you have a list or set of instances of Point representing the set of latitude/longitude pairs you want to select from.
List<Point> points;
Just generate a random integer between 0 and (set size -1). Use that random integer as an index into the list.
int index = Random(0, points.Length-1);
Point myRandomPoint = points[index];
Now use that Point in your call to Google
myLatlng = new google.maps.LatLng(myRandomPoint.Latitude, myRandomPoint.Longitude);

finding locations within a particular distance using db2

I am using html5 geolocation api to get my position in latitude and longitude. I want to store them in a table of locations and want to retrieve those locations within a particular distance.
my current latitudes and longitudes are stored in variables "latval", "longval", "distance"
My table is "location"
columns are "location", "lat", "long"
I am using DB2 Express C as database and latitude and longitude columns are set as double type now. What type should I use to store these values and what would be the query to get location names within a distance
Thank you.
It looks like there's an extension for Express C that includes Spatial processing. I've never used it (and can't seem to get access at the moment), so I can't speak to it. I'm assuming that you'd want to use that (find all locations within a radius is a pretty standard query).
If for some reason you can't use the extension, here's what I would do:
Keep your table as-is, or maybe use a float data-type, although please use full attribute names (there's no reason to truncate them). For simple needs, the name of the 'location' can be stored in the table, but you may want to give it a numeric id if more than one thing is at the same location (so actual points are only in there once).
You're also going to want indicies covering latitude and longitude (probably one each way, or one covering each column).
Then, given a starting position and distance, use this query:
SELECT name, latitude, longitude
FROM location
WHERE (latitude >= :currentLatitude - :distance
AND latitude <= :currentLatitude + :distance)
AND (longitude >= :currentLongitude - :distance
AND longitude <= :currentLongitude + :distance)
-- The previous four lines reduce the points selected to a box.
-- This is, or course, not completely correct, but should allow
-- the query to use the indicies to greatly reduce the initial
-- set of points evaluated.
-- You may wish to flip the condition and use ABS(), but
-- I don't think that would use the index...
AND POWER(latitude - :currentLatitude, 2) + POWER(longitude - :currentLongitude, 2)
<= POWER (:distance, 2)
-- This uses the pythagorean theorem to find all points within the specified
-- distance. This works best if the points have been pre-limited in some
-- way, because an index would almost certainly not be used otherwise.
-- Note that, on a spherical surface, this isn't completely accurate
-- - namely, distances between longitude points get shorter the farther
-- from the equator the latitude is -
-- but for your purposes is likely to be fine.
EDIT:
Found this after searching for 2 seconds on google, which also reminded me that :distance would be in the wrong units. The revised query is:
WITH Nearby (name, latitude, longitude, dist) as (
SELECT name, latitdude, longitude,
ACOS(SIN(RADIANS(latitude)) * SIN(RADIANS(:currentLatitude)) +
COS(RADIANS(latitude)) * COS(RADIANS(:currentLatitude)) *
COS(RADIANS(:currentLongitude - longitude))) * :RADIUS_OF_EARTH as dist
FROM location
WHERE (latitude >= :currentLatitude - DEGREES(:distance / :RADIUS_OF_EARTH)
AND latitude <= :currentLatitude + DEGREES(:distance / :RADIUS_OF_EARTH))
AND (longitude >= :currentLongitude -
DEGREES(:distance / :RADIUS_OF_EARTH / COS(RADIANS(:currentLatitude)))
AND longitude <= :currentLongitude +
DEGREES(:distance / :RADIUS_OF_EARTH / COS(RADIANS(:currentLatitude))))
)
SELECT *
FROM Nearby
WHERE dist <= :distance
Please note that wrapping the distance function in a UDF marked DETERMINISTIC would allow it to be placed in both the SELECT and HAVING portions, but only actually be called once, eliminating the need for the CTE.

ElasticSearch Script Field Returns Incorrect Longitude Value

When I add:
fields: [ "doc['Location'].lon" ]
to my query, the longitude value is different that what is shown in the document source.
Here you can see the results of a query where I fetched the doc['Latitude'].lon and .lat, and the _source.Latitude to compare:
https://gist.github.com/d9533170f1f50fd27e87 (note - these have been passed through json_decode in PHP, but the data is the same before using json_decode.)
I first noticed this when I was using "doc['field_name'].distance(lat, lon)" to try and add the distance as a field to my query. I tried both the "script_fields" and "fields" keys and each had the same result.
UPDATE: I noticed that the "doc['Location'].lon" is returning what I thought should be the doc['Location'].lat (the lat and lon are switched.)
The problem was that when using GeoJSON format (or using lat/long as an array) you have to switch the order of lat/lng to lng/lat.
I am rebuilding my index, but, in order to work around this I have used this query for now:
doc['Location'].distance( lon + 180, lat ) // Temporary bandaid
Once I've rebuilt the index with the correct values I'll switch back to:
doc['field_name'].distance(lat, lon) // The correct method

Resources