I have this onscreen joystick which moves sprite around by changing it's position and it works well. I've made some walls for the sprite to collide with (using Physics). And it's not going further as expected but if I keep going into a wall sprite seems to flicker (change it's position for a millisecond and going right back)
override func update(deltaTime seconds: TimeInterval) {
cNode.position = CGPoint(x: playerCurrentPosition.x + xChange,
y: playerCurrentPosition.y + yChange)
}
Did some more debugging and it seems for one update sprite's position is incorrect:
pos Y: -19.168764114379883
pos Y: -19.164892196655273
pos Y: -19.16112518310547
pos Y: -29.928884506225586. <---
pos Y: -19.15281105041504
pos Y: -19.148771286010742
Update:
Okay, I've tried moving with move By like so :
print("[", xChange,", ",yChange,"]", cNode.position.y)
cNode.run(SKAction.moveBy(x: xChange, y: yChange, duration: 1/60))
And I got the same flicker on Y position:
xChange, yChange, cNode.position.y
[ -0.08623046134167665 , 0.4925081801724735 ] -19.026506423950195
[ -0.08623046134167665 , 0.4925081801724735 ] -19.026336669921875
[ -0.08623046134167665 , 0.4925081801724735 ] -19.02557373046875
[ -0.08623046134167665 , 0.4925081801724735 ] -29.92888641357422
[ -0.08623046134167665 , 0.4925081801724735 ] -29.928884506225586
[ -0.08623046134167665 , 0.4925081801724735 ] -29.928884506225586
[ -0.08623046134167665 , 0.4925081801724735 ] -29.928884506225586
[ -0.08623046134167665 , 0.4925081801724735 ] -19.02621841430664
[ -0.08623046134167665 , 0.4925081801724735 ] -19.025728225708008
[ -0.08623046134167665 , 0.4925081801724735 ] -19.02647590637207
[ -0.08623046134167665 , 0.4925081801724735 ] -19.02564811706543
[ -0.08623046134167665 , 0.4925081801724735 ] -19.02585792541504
[ -0.08623046134167665 , 0.4925081801724735 ] -19.02660369873047
[ -0.08623046134167665 , 0.4925081801724735 ] -19.025630950927734
[ -0.08623046134167665 , 0.4925081801724735 ] -19.026046752929688
[ -0.08623046134167665 , 0.4925081801724735 ] -19.026309967041016
[ -0.08623046134167665 , 0.4925081801724735 ] -19.025686264038086
Update 2:
I've made a recording of the issue: Here
Update 3:
It seems my outer green rect had some collision masks, I removed those and it got better, but still there's some bouncing, have a look: Here
(red box is pinned to the green one)
The problem is almost certainly the fact that you are using code - triggered by the joystick - to set the sprite's position directly yet the sprite and the wall cannot overlap due to their physics bodies 'collisionBitMask` settings.
So the sprite is up against the wall and you use the joystick to move the sprite towards the wall. You update the sprite's position which places it overlapping the wall node. The SK engine never saw the 2 nodes begin to overlap but suddenly sees that these nodes overlap massively when they shouldn't and attempts to move them via an impulse so that they don't overlap anymore, causing the sprite to 'jump' to a new position where it doesn't overlap and so it appears to flicker.
You could avoid this my using an SKAction to move the sprite in response to the joystick input which I think will let the SK engine trap the collision between the wall and the spite as soon as they start to overlap and you could use contact detection to then stop the movement.
Related
I am building a MongoDB database of property data in the Netherlands. I want to be able to perform geospatial queries on my dataset. Each document does not have longitude and latitude coordinates, but something called "Rijksdriehoeks" coordinates. These Rijksdriehoeks coordinates do not conform to MongoDB's requirements for 2d coordinate pairs, in that they can exceed values of 600.000 (this system uses meters for units). This is a problem, because creating a 2d index requires all coordinate pairs to use longitude and latitude and thus to have values between [-180, 180] and [-90, 90], respectively.
I need to create a geo index for this dataset to reduce query time to acceptable levels, but creating a "legacy" 2d index will give this error because of the issue described above:
> db.Bag3DMembers.createIndex( { "properties.bbox" : "2d" })
{
"ok" : 0,
"errmsg" : "point not in interval of [ -180, 180 ] :: caused by :: { _id: ObjectId('5dfa7596cc0b7324e5331509'), type: \"Feature\", properties: { identificatie: \"0003100000117485\", aanduidingrecordinactief: false, aanduidingrecordcorrectie: 0, officieel: false, inonderzoek: false, documentnummer: \"FB 2010/PANDEN001\", documentdatum: \"2010-07-20\", bouwjaar: \"1991-01-01\", begindatumtijdvakgeldigheid: null, einddatumtijdvakgeldigheid: null, gemeentecode: \"0003\", ground-000: -0.43, ground-010: -0.34, ground-020: -0.31, ground-030: -0.3, ground-040: -0.27, ground-050: -0.25, roof-025: 10.58, rmse-025: 1.5, roof-050: 13.43, rmse-050: 1.28, roof-075: 13.46, rmse-075: 1.28, roof-090: 13.52, rmse-090: 1.27, roof-095: 13.87, rmse-095: 1.27, roof-099: 14.35, rmse-099: 1.27, roof_flat: false, nr_ground_pts: 220, nr_roof_pts: 6816, ahn_file_date: null, ahn_version: 2, height_valid: true, tile_id: \"07fz1\", gid: \"1\", bbox: [ [ 254052.046875, 593486.3125 ], [ 254076.625, 593504.6875 ] ] }, geometry: { type: \"Polygon\", coordinates: [ [ [ 254059.737, 593504.637, 0.0 ], [ 254059.227, 593500.0, 0.0 ], [ 254059.216, 593499.899, 0.0 ], [ 254058.242, 593500.0, 0.0 ], [ 254057.914, 593500.034, 0.0 ], [ 254057.893, 593500.0, 0.0 ], [ 254057.807, 593499.863, 0.0 ], [ 254052.074, 593490.692, 0.0 ], [ 254052.182, 593490.639, 0.0 ], [ 254058.138, 593490.002, 0.0 ], [ 254057.932, 593488.165, 0.0 ], [ 254074.487, 593486.4129999999, 0.0 ], [ 254075.981, 593500.0, 0.0 ], [ 254076.265, 593502.583, 0.0 ], [ 254076.561, 593502.55, 0.0 ], [ 254076.594, 593502.847, 0.0 ], [ 254059.737, 593504.637, 0.0 ] ] ] } }",
"code" : 13027,
"codeName" : "Location13027"
}
Is there any way I can persuade MongoDB to accept my "Rijksdriehoeks" coordinates or will I need to convert them to longitude and latitude values?
Check documentation Create a 2d Index:
On 2d indexes you can change the location range.
You can build a 2d geospatial index with a location range other than
the default. Use the min and max options when creating the index.
Would be
db.Bag3DMembers.createIndex(
{ "properties.bbox" : "2d" },
{ min: -10000, max: 630000, bits: 24 }
)
Below is the biz document, in it address.location is where I saved the coordinates.
{
"_id" : ObjectId("59944c26085e1140d4575393"),
"category" : "place",
"address" : {
"streetAddress" : "19210 Clay Road",
"city" : "Katy",
"zipcode" : "77449",
"state" : "Texas",
"country" : "United States",
"countryCode" : "US",
"locality" : "Katy, TX",
"location" : {
"type" : "Point",
"coordinates" : [
-95.7043599,
29.832139
]
},
"fomattedAddress" : "19210 Clay Rd, Katy, TX 77449"
}
}
With the below logic I calculated the polygon
Coordinate[] coordinates = new Coordinate[] {new Coordinate(-84.529793, 33.961886), new Coordinate( -84.521698, 33.952987),
new Coordinate(-84.517242, 33.944534), new Coordinate(-84.513290, 33.937264), new Coordinate( -84.498865, 33.915202), new Coordinate(-84.529793, 33.961886)};
GeometryFactory geometryFactory = new GeometryFactory();
LinearRing linear = new GeometryFactory().createLinearRing(coordinates);
Polygon polygon = new Polygon(linear, null, geometryFactory);
Coordinate[] polyCoordinates = polygon.getCoordinates();
With the below mongo query I am trying to get the businesses inside the polygon, but I get no results, am i doing somthing wrong please guide me
db.business.find(
{
"address.location.coordinates": {
$geoIntersects: {
$geometry: {
type: "Polygon" ,
coordinates: [
[ [ -84.529793, 33.961886 ], [ -84.521698, 33.952987 ], [ -84.517242, 33.944534 ], [-84.51329, 33.937264] , [ -84.498865, 33.915202 ], [-84.529793, 33.961886] ]
]
}
}
}
}
)
To find all points within certain distance along the route you need to build a poly around the route.
On the image below I assumed the whole route (green) is a straight line for brevity and clarity. Your query is an $or of 3 shapes - blue start and end point circles with radius R, and a red poly that joins both:
Following javascript code https://jsfiddle.net/961kcxr3/ calculates coordinates for a segment using basic flat geometry. This is what you need to do on application level using your language of choice:
const routeCoords [ [ -84.529793, 33.961886 ], [ -84.521698, 33.952987 ], [ -84.517242, 33.944534 ], [-84.51329, 33.937264] , [ -84.498865, 33.915202 ] ] ];
const R = 1000; // 1 km - radius to search within, adjust to your needs
const M = 1/98000; // radius to radians multiplier
const A = routeCoords[0];
const B = routeCoords[4];
const a = Math.atan2(B[0] - A[0], B[1] - A[1]) + Math.PI / 2;
var polyCoords = [
[
A[0] - Math.sin(a) * R * M,
A[1] - Math.cos(a) * R * M
], [
B[0] - Math.sin(a) * R * M,
B[1] - Math.cos(a) * R * M
], [
B[0] + Math.sin(a) * R * M,
B[1] + Math.cos(a) * R * M
], [
A[0] + Math.sin(a) * R * M,
A[1] + Math.cos(a) * R * M
]
];
Which gives you coordinates of the poly:
[
[-84.516182, 33.970903],
[-84.485254, 33.924219],
[-84.512476, 33.906185],
[-84.543404, 33.952869]
]
And the resulting query:
db.business.find(
{ $or: [
{ "address.location.coordinates": {
$geoWithin: {
$geometry: {
type: "Polygon" ,
coordinates: [ [
[-84.516182, 33.970903],
[-84.485254, 33.924219],
[-84.512476, 33.906185],
[-84.543404, 33.952869],
[-84.516182, 33.970903] // the first point to close the poly
] ]
}
},
} },
{ "address.location.coordinates": {
$geoWithin: {
$centerSphere: [ [ -84.529793, 33.961886 ], 1 / 6378.1 ]
}, // 1 km radius, adjust to your needs
} },
{ "address.location.coordinates": {
$geoWithin: {
$centerSphere: [ [ -84.498865, 33.915202 ], 1 / 6378.1 ]
}, // 1 km radius, adjust to your needs
} }
] }
)
The real-life code should calculate polygons and circles for each segment. It can result with quite large query, so be reasonable balancing between accuracy and speed.
Some cases for optimisation:
if length of a segment is significantly less than the radius R you can skip the poly and use 2 or 1 circle for the segment.
if angle a is the same for 2 consecutive segments, you can join the ends and treat them as a single segment the same way I joined 4 segments in the example above
I am using mongodb with polygons stored with geometry in this format
"geometry" : { "type" : "Polygon", "coordinates" : [ [ [ 2.0315, 85.8546219515 ], [ 2.0315, 86.1673780485 ], [ 1.7185, 86.1673780485 ], [ 1.7185, 85.8546219515 ], [ 2.0315, 85.8546219515 ] ] ] }
I am trying to use geoIntersect and query a rectangle polygon using something like this:
find({geometry:{$geoIntersects:{$geometry:{"type": "Polygon", "coordinates":[ [[12,20], [13,20], [13,18], [12,18], [12,20]]]}}}})
When I do small queries like that, the results are fine, but when I expand to really large boxes:
find({geometry:{$geoIntersects:{$geometry:{"type": "Polygon", "coordinates":[ [[-166.2890625,46.55886030311719], [-166.2890625,47.39834920035926], [12.12890625,47.39834920035926], [12.12890625,46.55886030311719], [-166.2890625,46.55886030311719]]]}}}})
then I start getting really odd results like
"geometry" : { "type" : "Polygon", "coordinates" : [ [ [ 2.9684999999999997, 85.54162195149999 ], [ 2.9684999999999997, 85.8543780485 ], [ 2.6555, 85.8543780485 ], [ 2.6555, 85.54162195149999 ], [ 2.9684999999999997, 85.54162195149999 ] ] ] }
I am only returned a few polygons (4 total) from the db that are actually inside my input polygon:
"geometry":{"type":"Polygon","coordinates":[[[12.343499999999999,47.1416219515],[12.343499999999999,47.454378048500004],[12.0305,47.454378048500004],[12.0305,47.1416219515],[12.343499999999999,47.1416219515]]]}}
"geometry":{"type":"Polygon","coordinates":[[[12.343499999999999,46.829621951499995],[12.343499999999999,47.1423780485],[12.0305,47.1423780485],[12.0305,46.829621951499995],[12.343499999999999,46.829621951499995]]]}}
"geometry":{"type":"Polygon","coordinates":[[[-166.0935,46.5166219515],[-166.0935,46.829378048500004],[-166.4065,46.829378048500004],[-166.4065,46.5166219515],[-166.0935,46.5166219515]]]}}
"geometry":{"type":"Polygon","coordinates":[[[-166.0935,46.829621951499995],[-166.0935,47.1423780485],[-166.4065,47.1423780485],[-166.4065,46.829621951499995],[-166.0935,46.829621951499995]]]}}
I shouldn't have any latitudes in the 80's with my input. I don't know where these are coming from. They make up the majority of what is returned. (847/851 results)
I don't think the polygon fits in one hemisphere. From the $geoIntersects docs,
Any geometry specified with GeoJSON to $geoIntersects queries, must fit within a single hemisphere.
Hi i have an COllection with an 2d sphere index
wayCollection.createIndex(new BasicDBObject("poly", "2dsphere"));
i when i try to insert a certain object i get an error:
Exception in thread "main" com.mongodb.WriteConcernException: { "serverUsed" : "localhost:27017" , "ok" : 1 , "n" : 0 , "err" : "insertDocument :: caused by :: 16755 Can't extract geo keys from object, malformed geometry?: { _id: ObjectId('53a89dc6a0042baf54050037'), id: 24837452, version: \"64\", changeset: \"13731788\", uid: \"362915\", user: \"micha555\", timestamp: \"2012-11-03T09:11:23Z\", poly: { type: \"Polygon\", coordinates: [ [ [ 9.1244131, 50.0109503 ], [ 9.120464800000001, 50.0099731 ], [ 9.116641, 50.0077
although the multipolygon ring is closed (first and last coordinate is the same)
any ideas?
Here is another polygon which is rejected:
{
"type":"Polygon",
"coordinates":[
[
[
9.0496053,
51.3255584
],
[
9.0492235,
51.32532
],
[
9.0495831,
51.3251321
],
[
9.049917199999999,
51.3253429
],
[
9.0496053,
51.3255584
],
[
9.049984500000001,
51.3258463
],
[
9.0505795,
51.3262127
],
[
9.050045600000001,
51.326574
],
[
9.0496432,
51.3263928
],
[
9.049625300000001,
51.3262806
],
[
9.0495628,
51.3261244
],
[
9.0495316,
51.3259341
],
[
9.0495471,
51.3257127
],
[
9.0496053,
51.3255584
]
]
]
}
when i paste it here it seems to be ok: http://geojsonlint.com/
maybe mongo db does not like when a point is used twice
The polygon is self-intersecting:
MongoDB prohibits such polygons.
First thing I would do is check your polygon at http://geojsonlint.com/ . If it does not pass then you know you have an issue with your data points (which has caused this error for many people previously).
If it does pass then I would check this bug that was recently reported and submitted to MongoDB: https://jira.mongodb.org/browse/SERVER-13735 . Basically a valid MultiPolygon is causing an error with the 2dsphere index on MongoDB 2.6.X. Others have reported similar issues so my bet is that it's a bug, or some undocumented limitation.
I'd vote up the issue on JIRA and add your voice to the comments - the more people let MongoDB know that this bug exists and is impacting them the faster it will get fixed.
I insert many polygons into MongoDB(2.4.8), and hope find the polygon a specified Point sits in. It seems a common question. But after reading all docs from google, I didn't get the result. So create this question.
e.g.
db.addr_poly.insert(
{ loc :
{ type : "Polygon" ,
coordinates : [ [ [ 0 , 0 ] , [ 3 , 6 ] , [ 6 , 1 ] , [ 0 , 0 ] ] ]
} })
db.addr_poly.insert(
{ loc :
{ type : "Polygon" ,
coordinates : [ [ [ 0 , 0 ] , [ -3 , -6 ] , [ -6 , -1 ] , [ 0 , 0 ] ] ]
} })
Now how to find the polygon which contains Point(1,1)?
Anybody can help me? Thanks a lot!
Use the $geoIntersects operator. It queries for all shapes which intersect the GeoJSON object you pass. When you pass a point to it, it should return all shapes which include that point. Keep in mind that the $geoIntersects operator only works for 2dsphere indexes, not for 2d indexes.
As #philipp said, you should use the $geoIntesects operator. I was having the hardest time trying to figure out the query. I figured I would share what it looks and it might save someone the trouble later.
db.addr_poly.find({
loc:{
$geoIntersects: {
$geometry: {
type: "Point" ,
coordinates: [1, 1]
}
}
}
});