Problems extracting values from geojson - geojson

I'm struggling to create an array of the values for D01. This is the first feature in my geojson variable:
county = [{
"type": "FeatureCollection",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:EPSG::4269" } },
"features": [
{ "type": "Feature", "properties": { "NAMELSAD10": "St. Clair County", "D01": 5.650500, "D02": 0.504000, "D03": 0.495000, "D04": 48.100000, "D05": 0.199000, "D06": 0.965000, "D07": 0.038000, "D08": 0.031000, "D09": 0.211000 }, "geometry": { "type": "Polygon", "coordinates": [
//so many coordinate pairs
] } } ] ]
To clarify, I want [5.650500, ...]
From this post I used:
help = county.features.map(function(f){
return f.properties.D01;
})
which gives the error: Cannot read property "map" of undefined.
Thinking some of my values might be null, I wrote this:
var help = new Array();
try{
help = county.features.map(function(f){
return f.properties.D01;
})
}catch(e){}
console.log(help);
which results in [], the blank 'help' array being written.
It seems I'm not accessing what I want to here. Can someone please point me in the right direction?

Your county seems an Array.
try this:
county[0].features.map(function(f){
return f.properties.D01;
})

Related

How to extract a nested nullable Avro Schema

The complete schema is the following:
{
"type": "record",
"name": "envelope",
"fields": [
{
"name": "before",
"type": [
"null",
{
"type": "record",
"name": "row",
"fields": [
{
"name": "username",
"type": "string"
},
{
"name": "timestamp",
"type": "long"
}
]
}
]
},
{
"name": "after",
"type": [
"null",
"row"
]
}
]
}
I wanted to programmatically extract the following sub-schema:
{
"type": "record",
"name": "row",
"fields": [
{
"name": "username",
"type": "string"
},
{
"name": "timestamp",
"type": "long"
}
]
}
As you see, field "before" is nullable. I can extract it's schema by doing:
schema.getField("before").schema()
But the schema is not a record as it contains NULL at the beginning(UNION type) and I can't go inside to fetch schema of "row".
["null",{"type":"record","name":"row","fields":[{"name":"username","type":"string"},{"name":"tweet","type":"string"},{"name":"timestamp","type":"long"}]}]
I want to fetch the sub-schema because I want to create GenericRecord out of it. Basically I want to create two GenericRecords "before" and "after" and add them to the main GenericRecord created from full schema.
Any help will be highly appreciated.
Good news, if you have a union schema, you can go inside to fetch the list of possible options:
Schema unionSchema = schema.getField("before").schema();
List<Schema> unionSchemaContains = unionSchema.getTypes();
At that point, you can look inside the list to find the one that corresponds to the Type.RECORD.

Azure Search - Query Collection of GeographyPoint

I am trying to query a collection GeographyPoint within a given range from my index. I am using Azure Search.
My index contains a list of GeographyPoint
public class Parent
{
public List<Child> Coordinates {get; set;}
}
public class Child
{
public GeographyPoint Coordinates { get; set; }
}
I know if there was a single property named location on the index you could query it with something like:
$filter=geo.distance(location, geography'POINT(-82.51571 31.89063)') le 0.1524
but how do you query a collection? I've tried using the any/all filters like:
$filter=geo.distance(IndexedCompany/Offices/any(c: c/PhysicalAddress/Coordinates), geography'POINT(-82.51571 31.89063)') le 0.1524
but I get the error: "Invalid expression: The Any/All query expression must evaluate to a single boolean value.\r\nParameter name: $filter"
Any help on how to query a collection of GeographyPoint would be much appreciated.
The issue is in how you've constructed your filter. Let's break it down using types, since that's the easiest way to see where things went wrong.
$filter=geo.distance(IndexedCompany/Offices/any(c: c/PhysicalAddress/Coordinates), geography'POINT(-82.51571 31.89063)') le 0.1524
Starting from the outside in, the top-most expression in a filter must be Boolean, and that checks out here because you're comparing geo.distance (which returns Edm.Double) with a literal distance using le. So that part is fine.
Next, let's look at geo.distance. It takes two points of type Edm.GeographyPoint and returns an Edm.Double. The second parameter is a literal point, so that's fine, but the first parameter is not. Let's look at that next.
The first parameter to geo.distance here is the expression IndexedCompany/Offices/any(c: c/PhysicalAddress/Coordinates). Although it's really an operator, you can think of any as a kind of function that returns a Boolean. That would be a problem, because geo.distance is expecting a point, not a Boolean. That's our first clue to what's wrong here, but it doesn't actually explain the error message you're seeing. Let's dig further to understand that.
Assume for the moment that the expression IndexedCompany/Offices/any(c: c/PhysicalAddress/Coordinates) was your entire filter. You'd still get the same error message: "Invalid expression: The Any/All query expression must evaluate to a single boolean value." To see why, consider what any and all expect in terms of types. Each one iterates over a collection of some type, applying a predicate in the form of a lambda expression to each element. That lambda expression in this case is c/PhysicalAddress/Coordinates, which (I'm assuming) is an Edm.GeographyPoint, not a Boolean.
Taking a step back, it helps to think about the cardinalities involved here. Each document contains a company, which has many offices, which each has a geo-point location. I'm assuming the goal is to match the whole document in case any of those co-ordinates match the filter. In that case, you really just need to re-order the parts of your query so that the types and cardinalities line up:
$filter=IndexedCompany/Offices/any(office: geo.distance(office/PhysicalAddress/Coordinates, geography'POINT(-82.51571 31.89063)') le 0.1524)
The filter is still a Boolean expression because that's the type of any. The lambda passed to any takes an Office, applies geo.distance to its geo-location, and compares the distance to the desired value. Now everything type checks and the iteration is happening the right place.
Example: search=*
"value": [
{
"#search.score": 1,
"id": "myid1",
"pts": [
{
"type": "Point",
"coordinates": [ 0, 0 ],
"crs": { "type": "name", "properties": { "name": "EPSG:4326" } }
},
{
"type": "Point",
"coordinates": [ 0, 1 ],
"crs": { "type": "name", "properties": { "name": "EPSG:4326" } }
}
]
},
{
"#search.score": 1,
"id": "myid2",
"pts": [
{
"type": "Point",
"coordinates": [ 0, 10 ],
"crs": { "type": "name", "properties": { "name": "EPSG:4326" } }
},
{
"type": "Point",
"coordinates": [ 0, 11 ],
"crs": { "type": "name", "properties": { "name": "EPSG:4326" } }
}
]
}
]
Example $filter=pts/any(pt: geo.distance(pt, geography'POINT(0 2)') le 111.3192394008)
"value": [
{
"#search.score": 1,
"id": "myid1",
"pts": [
{
"type": "Point",
"coordinates": [ 0, 0 ],
"crs": { "type": "name", "properties": { "name": "EPSG:4326" } }
},
{
"type": "Point",
"coordinates": [ 0, 1 ],
"crs": { "type": "name", "properties": { "name": "EPSG:4326" } }
}
]
}
]

Storing a List in a Vertex using Gremlin and Azure Cosmos Graph

I am trying to store a list of changes made to a Vertex in the Vertex itself. Ideally I would want something like this:
{
"id": "95fcfa87-1c03-436d-b3ca-340cea926ee9",
"label": "person",
"type": "vertex",
"log": [{
"user": "user#user.dk",
"action": "update",
"timestamp": "22-03-2017",
"field": "firstName",
"oldValue": "Marco"
}
]
}
Using this method chain I am able to a achieve the following structure
graph.addV('person')
.property('firstName', 'Thomas')
.property(list, 'log', '22-03-2017')
.properties('log')
.hasValue('22-03-2017', '21-03-2017')
.property('user','user#user.dk')
.property('action', 'update')
.property('field', 'firstName')
.property('oldValue', 'Marco')
{
"id": "95fcfa87-1c03-436d-b3ca-340cea926ee9",
"label": "person",
"type": "vertex",
"properties": {
"firstName": [{
"id": "f23482a9-48bc-44e0-b783-3b74a2439a11",
"value": "Thomas"
}
],
"log": [{
"id": "5cfa35e1-e453-42e2-99b1-eb64cd853f22",
"value": "22-03-2017",
"properties": {
"user": "user#user.dk",
"action": "update",
"field": "firstName",
"oldValue": "Marco"
}
}
]
}
}
However this seems overly complex, as I will have to store a value and add properties to it.
Is it possible to add anonymous objects (i.e. without id and value) with the above mentioned data?
Not an actual solution to storing proper objects in a history log, but if you just use it as a log and don't have to access or query it by its properties, you could just put the serialised JSON in the value?
Something like along these lines should approximate the structure you're requesting:
dynamic entry = new JObject();
entry.user = "user#user.dk";
entry.action = "update";
entry.timestamp = "22-03-2017 12:34:56";
entry.field = "firstName";
entry.oldValue = "Marco";
graph.addV('person')
.property('firstName', 'Thomas')
.property(list, 'log', entry.ToString());
{
"id": "95fcfa87-1c03-436d-b3ca-340cea926ee9",
"label": "person",
"type": "vertex",
"properties": {
"firstName": [{
"id": "f23482a9-48bc-44e0-b783-3b74a2439a11",
"value": "Thomas"
}
],
"log": [{
"id": "5cfa35e1-e453-42e2-99b1-eb64cd853f22",
"value": "{\"user\":\"user#user.dk\",\"action\":\"update\",\"timestamp\":\"22-03-2017\",\"field\":\"firstName\",\"oldValue\":\"Marco\"}"
}
]
}
}
These log entries can easily be read, deserialised, used, and presented, but will not do much for queriability.

d3.geoPath() returns Error: <path> attribute d: Expected number, "M,ZM,ZM,ZM,Z"

Edit: recreated the logic on jsfiddle https://jsfiddle.net/exLtcgrq/1/
I am trying to parse a simple GeoJSON file to D3 using the D3 V4 API.
My GeoJSON is simple:
{ "type": "FeatureCollection",
"features": [
{ "type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[10.0, 10.0], [60.0, 40.0], [50.0, 75.0],[20.0, 60.0]
]
},
"properties": {
"id": "1",
"Type": "campingspot"
}
},
{ "type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[20.0, 65.0], [50.0, 80.0], [50.0, 110.0],[20.0, 115.0]
]
},
"properties": {
"id": "1",
"Type": "campingspot"
}
}
]
}
I load thus using the d3.json() method and try using the d3-geo api to convert it to a path with this code:
var jsonData2 = d3.json("campingGeojson.json", function(error, json){
svg.selectAll("path")
.data(json.features)
.enter()
.append("path")
.attr("d", d3.geoPath())
.attr("stroke", "black")
.attr("stroke-width", 1)
.attr("fill", "green")
});
The console output on chrome tells me the following
Error: <path> attribute d: Expected number, "M,ZM,ZM,ZM,Z".
Any suggestions what is going wrong with using the geoPath method is highly appreciated.
Thank you.
Coordinates for geoJson polygons are an array of coordinate arrays (with the coordinates themselves being arrays). The first array indicates the shell, following arrays indicate holes.
So I think your geoJson should look more like:
"coordinates": [
[ [10.0, 10.0], [60.0, 40.0], [50.0, 75.0],[20.0, 60.0] ]
]

How can I describe complex json model in swagger

I'm trying to use Swagger to describe web-api I'm building.
The problem is that I can't understand how to describe complex json object?
For example, how to describe this objects:
{
name: "Jhon",
address: [
{
type: "home",
line1: "1st street"
},
{
type: "office",
line1: "2nd street"
}
]
}
Okay, so based on the comments above, you want the following schema:
{
"definitions": {
"user": {
"type": "object",
"required": [ "name" ],
"properties": {
"name": {
"type": "string"
},
"address": {
"type": "array",
"items": {
"$ref": "#/definitions/address"
}
}
}
},
"address": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [ "home", "office" ]
},
"line1": {
"type": "string"
}
}
}
}
}
I've made a few assumptions to make the sample a bit more complicated, to help in the future.
For the "user" object, I've declared that the "name" field is mandatory. If, for example, you also need the address to be mandatory, you can change the definition to "required": [ "name", "address" ].
We basically use a subset of json-schema to describe the models. Of course not everyone knows it, but it's fairly simple to learn and use.
For the address type you can see I also set the limit to two options - either home or office. You can add anything to that list, or remove the "enum" entirely to remove that constraint.
When the "type" of a property is "array", you need to accompany it with "items" which declares the internal type of the array. In this case, I referenced another definition, but that definition could have been inline as well. It's normally easier to maintain that way, especially if you need the "address" definition alone or within other models.
As requested, the inline version:
{
"definitions": {
"user": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string"
},
"address": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"home",
"office"
]
},
"line1": {
"type": "string"
}
}
}
}
}
}
}
}

Resources