{"__v":22,"_id":"5735a57131a73b1700887ca1","category":{"project":"54774d9af3736008009e9e0e","version":"56a0bd9e3697d80d002ac5e7","_id":"5735a52431a73b1700887ca0","__v":0,"sync":{"url":"","isSync":false},"reference":false,"createdAt":"2016-05-13T09:57:56.274Z","from_sync":false,"order":13,"slug":"data-objects","title":"Data Objects"},"parentDoc":null,"project":"54774d9af3736008009e9e0e","user":"54774c47f3736008009e9e0c","version":{"__v":20,"_id":"56a0bd9e3697d80d002ac5e7","project":"54774d9af3736008009e9e0e","createdAt":"2016-01-21T11:14:38.131Z","releaseDate":"2016-01-21T11:14:38.131Z","categories":["56a0bd9f3697d80d002ac5e8","56a0bd9f3697d80d002ac5e9","56a0bd9f3697d80d002ac5ea","56a0bd9f3697d80d002ac5eb","56b098a43a5b810d00745e3f","56b098da8f7a4f0d0029dd10","56d5a8ecf612b80b00fb69cd","570989853ab43c0e0072b2d6","571006aa10300c0e007f6133","5735a52431a73b1700887ca0","5744b0529e045c0e00b7a7a2","5744b1d0b56d431700d8a4fb","5744b1fb55d65a0e00b436e1","5744b218f9c7411700ce560e","5744b220f9c7411700ce560f","5744b2259e045c0e00b7a7a7","5744b22cf8b79f0e00de6a2d","5744b23155d65a0e00b436e4","5744b242c758290e00fbc235","5744b2569e045c0e00b7a7a8","5756a3f2bb92962900dafe3d","57ee23e81e42900e0014a42f","581c822c98676e0f00d240ef"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"Sockets","version_clean":"1.1.0","version":"1.1"},"updates":[],"next":{"pages":[],"description":""},"createdAt":"2016-05-13T09:59:13.408Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":5,"body":"## Chapter Contents:\n1. [Overview](#overview)\n2. [Creating Data Objects with a GeoPoint field](#creating-data-objects-with-a-geopoint-field)\n3. [Making GeoPoint queries](#making-geopoint-queries)\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Overview\"\n}\n[/block]\nSyncano allows for storing geographic coordinates. Thanks to `geopoints` you can, for instance, compare the distance between two users. You can also find out if a given place (e.g. restaurant) is within a range (5 miles) of a user. \n\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Creating Data Objects with a GeoPoint field\"\n}\n[/block]\nIn order to be able to use the GeoPoints functionality, you'll need a Data Class with a GeoPoint schema field type. You'll also need to add a filtering index to this field if you'd like to make GeoPoint based queries. You can add one filtering index to GeoPoint fields per Data Class.\n[block:callout]\n{\n  \"type\": \"info\",\n  \"body\": \"You can read more about adding schema fields and creating data classes in [this chapter.](doc:classes-overview)\",\n  \"title\": \"\"\n}\n[/block]\nOnce you have added the GeoPoint field type to your data class, you can start creating Data Objects with GeoPoints. If you named your GeoPoint field as `where_am_i`, the call would look more or less like this:\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"curl -X POST \\\\\\n-H \\\"X-API-KEY: API_KEY\\\" \\\\\\n-H \\\"Content-type: application/json\\\" \\\\\\n-d '{\\\"where_am_i\\\": {\\\"latitude\\\": 66.5433889, \\\"longitude\\\": 25.8447679}}' \\\\\\n\\\"https://api.syncano.rocks/v1.1/instances/INSTANCE/classes/DATA_CLASS/objects/\\\"\",\n      \"language\": \"curl\"\n    },\n    {\n      \"code\": \"Geo *geo = [Geo new];\\ngeo.whereAmI = [SCGeoPoint geoPointWithLatitude:66.5433889 longitude:25.8447679];\\n[geo saveWithCompletionBlock:^(NSError * _Nullable error) {\\n   //Handle error\\n}];\",\n      \"language\": \"objectivec\"\n    },\n    {\n      \"code\": \"let geo = Geo()\\ngeo.whereAmI = SCGeoPoint(latitude: 66.5433889, longitude: 25.844767)\\ngeo.saveWithCompletionBlock { (error) in\\n  //handle error\\n}\",\n      \"language\": \"swift\"\n    }\n  ]\n}\n[/block]\n\n[block:callout]\n{\n  \"type\": \"warning\",\n  \"body\": \"When creating GeoPoints you should remember that the valid ranges for the coordinates are:\\n- Latitude: -89 to 89\\n- Longitude -179 to 179\\n\\nYou can create coordinates with a 13 digit precision after decimal point.\"\n}\n[/block]\nThis is how a Data Object object with a `where_am_i` GeoPoint field will look like:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"// some fields were skipped for brevity\\n{\\n    \\\"id\\\": 2, \\n    \\\"created_at\\\": \\\"2016-05-16T14:39:22.804529Z\\\", \\n    \\\"updated_at\\\": \\\"2016-05-16T14:39:22.804551Z\\\", \\n    \\\"revision\\\": 1,  \\n    \\\"where_am_i\\\": {\\n        \\\"type\\\": \\\"geopoint\\\",\\n        \\\"latitude\\\": -30.0, \\n        \\\"longitude\\\": 23.0\\n    }\\n}\",\n      \"language\": \"json\"\n    }\n  ]\n}\n[/block]\n\nThat's it when it comes to creating Data Objects with GeoPoint fields. What you would probably like to know is how to make all those cool coordinate queries, so here it is.\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Making GeoPoint queries\"\n}\n[/block]\nThere are two ways of filtering the results based on spacial coordinates. You can query if objects are:\n1. [Near](#section-near-query)\n2. [Exist](#section-exist-query) \n\n\n### Near query\n\nMaking a `near` query will return all the objects that are within the given range.\n[block:callout]\n{\n  \"type\": \"info\",\n  \"body\": \"Default distance in `near` query is 100 miles\\n\\nMaximal distance is either 40075km or 24901miles (length of the equator).\"\n}\n[/block]\nA call with the default distance will look like this:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"curl -X GET \\\\\\n-H \\\"X-API-KEY: API_KEY\\\" \\\\\\n-g 'https://api.syncano.rocks/v1.1/instances/INSTANCE/classes/DATA_CLASS/objects/?query={\\\"where_am_i\\\":{\\\"_near\\\":{\\\"longitude\\\":66.5433889,\\\"latitude\\\":25.8447679}}}'\",\n      \"language\": \"curl\"\n    },\n    {\n      \"code\": \"SCPredicate *predicate = [SCPredicate whereKey::::at:::\\\"whereAmI\\\" isNearGeoPoint:[SCGeoPoint geoPointWithLatitude:25.8447679 longitude:66.5433889]];\\n[[Geo please] giveMeDataObjectsWithPredicate:predicate parameters:nil completion:^(NSArray * _Nullable objects, NSError * _Nullable error) {\\n\\t//Handle error\\n}];\",\n      \"language\": \"objectivec\"\n    },\n    {\n      \"code\": \"let predicate:SCPredicate = SCPredicate.whereKey(\\\"whereAmI\\\", isNearGeoPoint: SCGeoPoint(latitude: 25.8447679, longitude: 66.5433889))\\nGeo.please().giveMeDataObjects(withPredicate: predicate, parameters: nil) { (objects, error) in\\n //Handle error\\n}\",\n      \"language\": \"swift\"\n    }\n  ]\n}\n[/block]\nIf you would like to specify the range, you can pass an additional parameter. It could be either `distance_in_miles` or `distance_in_kilometers`:\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"# distance within range in kilometers\\ncurl -X GET \\\\\\n-H \\\"X-API-KEY: API_KEY\\\" \\\\\\n-g 'https://api.syncano.rocks/v1.1/instances/INSTANCE/classes/DATA_CLASS/objects/?query={\\\"where_am_i\\\":{\\\"_near\\\":{\\\"longitude\\\":66.5433889,\\\"latitude\\\":25.8447679,\\\"distance_in_kilometers\\\":1}}}'\\n\\n# distance within range in miles\\n\\ncurl -X GET \\\\\\n-H \\\"X-API-KEY: API_KEY\\\" \\\\\\n-g 'https://api.syncano.rocks/v1.1/instances/INSTANCE/classes/DATA_CLASS/objects/?query={\\\"where_am_i\\\":{\\\"_near\\\":{\\\"longitude\\\":66.5433889,\\\"latitude\\\":25.8447679,\\\"distance_in_miles\\\":1}}}'\",\n      \"language\": \"curl\"\n    },\n    {\n      \"code\": \"# distance within range in kilometers\\n\\n\\nSCPredicate *predicate = [SCPredicate whereKey:@\\\"whereAmI\\\" isNearGeoPoint:[SCGeoPoint geoPointWithLatitude:25.8447679 longitude:66.5433889]  withinKilometers:1];\\n[[Geo please] giveMeDataObjectsWithPredicate:predicate parameters:nil completion:^(NSArray * _Nullable objects, NSError * _Nullable error) {\\n    // Handle error\\n}];\\n\\n# distance within range in miles\\n\\nSCPredicate *predicate = [SCPredicate whereKey:@\\\"whereAmI\\\" isNearGeoPoint:[SCGeoPoint geoPointWithLatitude:25.8447679 longitude:66.5433889]  withinMiles:1];\\n[[Geo please] giveMeDataObjectsWithPredicate:predicate parameters:nil completion:^(NSArray * _Nullable objects, NSError * _Nullable error) {\\n    // Handle error\\n}];\",\n      \"language\": \"objectivec\"\n    },\n    {\n      \"code\": \"# distance within range in kilometers\\n\\nlet predicate:SCPredicate = SCPredicate.whereKey(\\\"whereAmI\\\", isNearGeoPoint: SCGeoPoint(latitude: 25.8447679, longitude: 66.5433889) , withinKilometers:1)\\nGeo.please().giveMeDataObjects(withPredicate: predicate, parameters: nil) { (objects, error) in\\n    //Handle error\\n}\\n\\n# distance within range in miles\\n\\nlet predicate:SCPredicate = SCPredicate.whereKey(\\\"whereAmI\\\", isNearGeoPoint: SCGeoPoint(latitude: 25.8447679, longitude: 66.5433889) , withinMiles:1)\\nGeo.please().giveMeDataObjects(withPredicate: predicate, parameters: nil) { (objects, error) in\\n   //Handle error\\n}\",\n      \"language\": \"swift\"\n    }\n  ]\n}\n[/block]\n\n### Exist query\n\nYou can also check if a given coordinates can be found in your Data Class. This is how such a lookup would look like:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"curl -X GET \\\\\\n-H \\\"X-API-KEY: API_KEY\\\" \\\\\\n-g 'https://api.syncano.rocks/v1.1/instances/INSTANCE/classes/DATA_CLASS/objects/?query={\\\"where_am_i\\\":{\\\"_exists\\\":true}}'\",\n      \"language\": \"curl\"\n    },\n    {\n      \"code\": \"SCPredicate *predicate = [SCPredicate whereKeyExists:@\\\"whereAmI\\\"];\\n[[Geo please] giveMeDataObjectsWithPredicate:predicate parameters:nil completion:^(NSArray * _Nullable objects, NSError * _Nullable error) {\\n    // Handle error\\n}];\",\n      \"language\": \"objectivec\"\n    },\n    {\n      \"code\": \"let predicate:SCPredicate = SCPredicate.whereKeyExists(\\\"whereAmI\\\")\\nGeo.please().giveMeDataObjects(withPredicate: predicate, parameters: nil) { (objects, error) in\\n    //Handle error\\n}\",\n      \"language\": \"swift\"\n    }\n  ]\n}\n[/block]\n\n\nThat's all about the GeoPoints. We hope you'll find them useful!","excerpt":"In this chapter you will learn about GeoPoint fields and how they are useful","slug":"geopoints","type":"basic","title":"GeoPoints"}

GeoPoints

In this chapter you will learn about GeoPoint fields and how they are useful

## Chapter Contents: 1. [Overview](#overview) 2. [Creating Data Objects with a GeoPoint field](#creating-data-objects-with-a-geopoint-field) 3. [Making GeoPoint queries](#making-geopoint-queries) [block:api-header] { "type": "basic", "title": "Overview" } [/block] Syncano allows for storing geographic coordinates. Thanks to `geopoints` you can, for instance, compare the distance between two users. You can also find out if a given place (e.g. restaurant) is within a range (5 miles) of a user. [block:api-header] { "type": "basic", "title": "Creating Data Objects with a GeoPoint field" } [/block] In order to be able to use the GeoPoints functionality, you'll need a Data Class with a GeoPoint schema field type. You'll also need to add a filtering index to this field if you'd like to make GeoPoint based queries. You can add one filtering index to GeoPoint fields per Data Class. [block:callout] { "type": "info", "body": "You can read more about adding schema fields and creating data classes in [this chapter.](doc:classes-overview)", "title": "" } [/block] Once you have added the GeoPoint field type to your data class, you can start creating Data Objects with GeoPoints. If you named your GeoPoint field as `where_am_i`, the call would look more or less like this: [block:code] { "codes": [ { "code": "curl -X POST \\\n-H \"X-API-KEY: API_KEY\" \\\n-H \"Content-type: application/json\" \\\n-d '{\"where_am_i\": {\"latitude\": 66.5433889, \"longitude\": 25.8447679}}' \\\n\"https://api.syncano.rocks/v1.1/instances/INSTANCE/classes/DATA_CLASS/objects/\"", "language": "curl" }, { "code": "Geo *geo = [Geo new];\ngeo.whereAmI = [SCGeoPoint geoPointWithLatitude:66.5433889 longitude:25.8447679];\n[geo saveWithCompletionBlock:^(NSError * _Nullable error) {\n //Handle error\n}];", "language": "objectivec" }, { "code": "let geo = Geo()\ngeo.whereAmI = SCGeoPoint(latitude: 66.5433889, longitude: 25.844767)\ngeo.saveWithCompletionBlock { (error) in\n //handle error\n}", "language": "swift" } ] } [/block] [block:callout] { "type": "warning", "body": "When creating GeoPoints you should remember that the valid ranges for the coordinates are:\n- Latitude: -89 to 89\n- Longitude -179 to 179\n\nYou can create coordinates with a 13 digit precision after decimal point." } [/block] This is how a Data Object object with a `where_am_i` GeoPoint field will look like: [block:code] { "codes": [ { "code": "// some fields were skipped for brevity\n{\n \"id\": 2, \n \"created_at\": \"2016-05-16T14:39:22.804529Z\", \n \"updated_at\": \"2016-05-16T14:39:22.804551Z\", \n \"revision\": 1, \n \"where_am_i\": {\n \"type\": \"geopoint\",\n \"latitude\": -30.0, \n \"longitude\": 23.0\n }\n}", "language": "json" } ] } [/block] That's it when it comes to creating Data Objects with GeoPoint fields. What you would probably like to know is how to make all those cool coordinate queries, so here it is. [block:api-header] { "type": "basic", "title": "Making GeoPoint queries" } [/block] There are two ways of filtering the results based on spacial coordinates. You can query if objects are: 1. [Near](#section-near-query) 2. [Exist](#section-exist-query) ### Near query Making a `near` query will return all the objects that are within the given range. [block:callout] { "type": "info", "body": "Default distance in `near` query is 100 miles\n\nMaximal distance is either 40075km or 24901miles (length of the equator)." } [/block] A call with the default distance will look like this: [block:code] { "codes": [ { "code": "curl -X GET \\\n-H \"X-API-KEY: API_KEY\" \\\n-g 'https://api.syncano.rocks/v1.1/instances/INSTANCE/classes/DATA_CLASS/objects/?query={\"where_am_i\":{\"_near\":{\"longitude\":66.5433889,\"latitude\":25.8447679}}}'", "language": "curl" }, { "code": "SCPredicate *predicate = [SCPredicate whereKey:@\"whereAmI\" isNearGeoPoint:[SCGeoPoint geoPointWithLatitude:25.8447679 longitude:66.5433889]];\n[[Geo please] giveMeDataObjectsWithPredicate:predicate parameters:nil completion:^(NSArray * _Nullable objects, NSError * _Nullable error) {\n\t//Handle error\n}];", "language": "objectivec" }, { "code": "let predicate:SCPredicate = SCPredicate.whereKey(\"whereAmI\", isNearGeoPoint: SCGeoPoint(latitude: 25.8447679, longitude: 66.5433889))\nGeo.please().giveMeDataObjects(withPredicate: predicate, parameters: nil) { (objects, error) in\n //Handle error\n}", "language": "swift" } ] } [/block] If you would like to specify the range, you can pass an additional parameter. It could be either `distance_in_miles` or `distance_in_kilometers`: [block:code] { "codes": [ { "code": "# distance within range in kilometers\ncurl -X GET \\\n-H \"X-API-KEY: API_KEY\" \\\n-g 'https://api.syncano.rocks/v1.1/instances/INSTANCE/classes/DATA_CLASS/objects/?query={\"where_am_i\":{\"_near\":{\"longitude\":66.5433889,\"latitude\":25.8447679,\"distance_in_kilometers\":1}}}'\n\n# distance within range in miles\n\ncurl -X GET \\\n-H \"X-API-KEY: API_KEY\" \\\n-g 'https://api.syncano.rocks/v1.1/instances/INSTANCE/classes/DATA_CLASS/objects/?query={\"where_am_i\":{\"_near\":{\"longitude\":66.5433889,\"latitude\":25.8447679,\"distance_in_miles\":1}}}'", "language": "curl" }, { "code": "# distance within range in kilometers\n\n\nSCPredicate *predicate = [SCPredicate whereKey:@\"whereAmI\" isNearGeoPoint:[SCGeoPoint geoPointWithLatitude:25.8447679 longitude:66.5433889] withinKilometers:1];\n[[Geo please] giveMeDataObjectsWithPredicate:predicate parameters:nil completion:^(NSArray * _Nullable objects, NSError * _Nullable error) {\n // Handle error\n}];\n\n# distance within range in miles\n\nSCPredicate *predicate = [SCPredicate whereKey:@\"whereAmI\" isNearGeoPoint:[SCGeoPoint geoPointWithLatitude:25.8447679 longitude:66.5433889] withinMiles:1];\n[[Geo please] giveMeDataObjectsWithPredicate:predicate parameters:nil completion:^(NSArray * _Nullable objects, NSError * _Nullable error) {\n // Handle error\n}];", "language": "objectivec" }, { "code": "# distance within range in kilometers\n\nlet predicate:SCPredicate = SCPredicate.whereKey(\"whereAmI\", isNearGeoPoint: SCGeoPoint(latitude: 25.8447679, longitude: 66.5433889) , withinKilometers:1)\nGeo.please().giveMeDataObjects(withPredicate: predicate, parameters: nil) { (objects, error) in\n //Handle error\n}\n\n# distance within range in miles\n\nlet predicate:SCPredicate = SCPredicate.whereKey(\"whereAmI\", isNearGeoPoint: SCGeoPoint(latitude: 25.8447679, longitude: 66.5433889) , withinMiles:1)\nGeo.please().giveMeDataObjects(withPredicate: predicate, parameters: nil) { (objects, error) in\n //Handle error\n}", "language": "swift" } ] } [/block] ### Exist query You can also check if a given coordinates can be found in your Data Class. This is how such a lookup would look like: [block:code] { "codes": [ { "code": "curl -X GET \\\n-H \"X-API-KEY: API_KEY\" \\\n-g 'https://api.syncano.rocks/v1.1/instances/INSTANCE/classes/DATA_CLASS/objects/?query={\"where_am_i\":{\"_exists\":true}}'", "language": "curl" }, { "code": "SCPredicate *predicate = [SCPredicate whereKeyExists:@\"whereAmI\"];\n[[Geo please] giveMeDataObjectsWithPredicate:predicate parameters:nil completion:^(NSArray * _Nullable objects, NSError * _Nullable error) {\n // Handle error\n}];", "language": "objectivec" }, { "code": "let predicate:SCPredicate = SCPredicate.whereKeyExists(\"whereAmI\")\nGeo.please().giveMeDataObjects(withPredicate: predicate, parameters: nil) { (objects, error) in\n //Handle error\n}", "language": "swift" } ] } [/block] That's all about the GeoPoints. We hope you'll find them useful!