Mongo: Fix reversing polygon coordinates (#4609)

* Fix reversing polygon coordinates

* comments fix

* real data test

* improved tests
This commit is contained in:
Diamond Lewis
2018-03-10 14:27:03 -06:00
committed by GitHub
parent c7235829c3
commit c6bc81caef
3 changed files with 118 additions and 11 deletions

View File

@@ -63,12 +63,29 @@ describe('parseObjectToMongoObjectForCreate', () => {
done();
});
it('plain', (done) => {
const geoPoint = {__type: 'GeoPoint', longitude: 180, latitude: -180};
it('parse geopoint to mongo', (done) => {
const lat = -45;
const lng = 45;
const geoPoint = {__type: 'GeoPoint', latitude: lat, longitude: lng};
const out = transform.parseObjectToMongoObjectForCreate(null, {location: geoPoint},{
fields: {location: {type: 'GeoPoint'}}
});
expect(out.location).toEqual([180, -180]);
expect(out.location).toEqual([lng, lat]);
done();
});
it('parse polygon to mongo', (done) => {
const lat1 = -45;
const lng1 = 45;
const lat2 = -55;
const lng2 = 55;
const lat3 = -65;
const lng3 = 65;
const polygon = {__type: 'Polygon', coordinates: [[lat1, lng1],[lat2, lng2],[lat3, lng3]]}
const out = transform.parseObjectToMongoObjectForCreate(null, {location: polygon},{
fields: {location: {type: 'Polygon'}}
});
expect(out.location.coordinates).toEqual([[[lng1, lat1],[lng2, lat2],[lng3, lat3],[lng1, lat1]]]);
done();
});
@@ -144,26 +161,31 @@ describe('parseObjectToMongoObjectForCreate', () => {
done();
});
it('geopoint', (done) => {
const input = {location: [45, -45]};
it('mongo geopoint to parse', (done) => {
const lat = -45;
const lng = 45;
const input = {location: [lng, lat]};
const output = transform.mongoObjectToParseObject(null, input, {
fields: { location: { type: 'GeoPoint' }},
});
expect(typeof output.location).toEqual('object');
expect(output.location).toEqual(
{__type: 'GeoPoint', longitude: 45, latitude: -45}
{__type: 'GeoPoint', latitude: lat, longitude: lng}
);
done();
});
it('polygon', (done) => {
const input = {location: { type: 'Polygon', coordinates: [[[45, -45],[45, -45]]]}};
it('mongo polygon to parse', (done) => {
const lat = -45;
const lng = 45;
// Mongo stores polygon in WGS84 lng/lat
const input = {location: { type: 'Polygon', coordinates: [[[lat, lng],[lat, lng]]]}};
const output = transform.mongoObjectToParseObject(null, input, {
fields: { location: { type: 'Polygon' }},
});
expect(typeof output.location).toEqual('object');
expect(output.location).toEqual(
{__type: 'Polygon', coordinates: [[45, -45],[45, -45]]}
{__type: 'Polygon', coordinates: [[lng, lat],[lng, lat]]}
);
done();
});

View File

@@ -160,6 +160,64 @@ describe('Parse.Polygon testing', () => {
}, done.fail);
});
it('polygonContain query no reverse input (Regression test for #4608)', (done) => {
const points1 = [[.25,0],[.25,1.25],[.75,1.25],[.75,0]];
const points2 = [[0,0],[0,2],[2,2],[2,0]];
const points3 = [[10,10],[10,15],[15,15],[15,10],[10,10]];
const polygon1 = new Parse.Polygon(points1);
const polygon2 = new Parse.Polygon(points2);
const polygon3 = new Parse.Polygon(points3);
const obj1 = new TestObject({location: polygon1});
const obj2 = new TestObject({location: polygon2});
const obj3 = new TestObject({location: polygon3});
Parse.Object.saveAll([obj1, obj2, obj3]).then(() => {
const where = {
location: {
$geoIntersects: {
$point: { __type: 'GeoPoint', latitude: 0.5, longitude:1.0 }
}
}
};
return rp.post({
url: Parse.serverURL + '/classes/TestObject',
json: { where, '_method': 'GET' },
headers: {
'X-Parse-Application-Id': Parse.applicationId,
'X-Parse-Javascript-Key': Parse.javaScriptKey
}
});
}).then((resp) => {
expect(resp.results.length).toBe(2);
done();
}, done.fail);
});
it('polygonContain query real data (Regression test for #4608)', (done) => {
const detroit = [[42.631655189280224,-83.78406753121705],[42.633047793854814,-83.75333640366955],[42.61625254348911,-83.75149921669944],[42.61526926650296,-83.78161794858735],[42.631655189280224,-83.78406753121705]];
const polygon = new Parse.Polygon(detroit);
const obj = new TestObject({location: polygon});
obj.save().then(() => {
const where = {
location: {
$geoIntersects: {
$point: { __type: 'GeoPoint', latitude: 42.624599, longitude:-83.770162 }
}
}
};
return rp.post({
url: Parse.serverURL + '/classes/TestObject',
json: { where, '_method': 'GET' },
headers: {
'X-Parse-Application-Id': Parse.applicationId,
'X-Parse-Javascript-Key': Parse.javaScriptKey
}
});
}).then((resp) => {
expect(resp.results.length).toBe(1);
done();
}, done.fail);
});
it('polygonContain invalid input', (done) => {
const points = [[0,0],[0,1],[1,1],[1,0]];
const polygon = new Parse.Polygon(points);
@@ -255,6 +313,24 @@ describe_only_db('mongo')('Parse.Polygon testing', () => {
}, done.fail);
});
it('polygon coordinates reverse input', (done) => {
const Config = require('../src/Config');
const config = Config.get('test');
// When stored the first point should be the last point
const input = [[12,11],[14,13],[16,15],[18,17]];
const output = [[[11,12],[13,14],[15,16],[17,18],[11,12]]];
const obj = new TestObject();
obj.set('polygon', new Parse.Polygon(input));
obj.save().then(() => {
return config.database.adapter._rawFind('TestObject', {_id: obj.id});
}).then((results) => {
expect(results.length).toBe(1);
expect(results[0].polygon.coordinates).toEqual(output);
done();
});
});
it('polygon loop is not valid', (done) => {
const coords = [[0,0],[0,1],[1,0],[1,1]];
const obj = new TestObject();

View File

@@ -1261,9 +1261,13 @@ var GeoPointCoder = {
var PolygonCoder = {
databaseToJSON(object) {
// Convert lng/lat -> lat/lng
const coords = object.coordinates[0].map((coord) => {
return [coord[1], coord[0]];
});
return {
__type: 'Polygon',
coordinates: object['coordinates'][0]
coordinates: coords
}
},
@@ -1283,7 +1287,8 @@ var PolygonCoder = {
},
JSONToDatabase(json) {
const coords = json.coordinates;
let coords = json.coordinates;
// Add first point to the end to close polygon
if (coords[0][0] !== coords[coords.length - 1][0] ||
coords[0][1] !== coords[coords.length - 1][1]) {
coords.push(coords[0]);
@@ -1306,6 +1311,10 @@ var PolygonCoder = {
'GeoJSON: Loop must have at least 3 different vertices'
);
}
// Convert lat/long -> long/lat
coords = coords.map((coord) => {
return [coord[1], coord[0]];
});
return { type: 'Polygon', coordinates: [coords] };
},