Could you please help me to find the right solution how to access to the individual points of multi-polygon object in mysql? Here is the object:
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[-105.00432014465332, 39.74732195489861],
[-105.00715255737305, 39.74620006835170],
[-105.00921249389647, 39.74468219277038],
[-105.01067161560059, 39.74362625960105],
[-105.01195907592773, 39.74290029616054],
[-105.00989913940431, 39.74078835902781],
[-105.00758171081543, 39.74059036160317],
[-105.00346183776855, 39.74059036160317],
[-105.00097274780272, 39.74059036160317],
[-105.00062942504881, 39.74072235994946],
[-105.00020027160645, 39.74191033368865],
[-105.00071525573731, 39.74276830198601],
[-105.00097274780272, 39.74369225589818],
[-105.00097274780272, 39.74461619742136],
[-105.00123023986816, 39.74534214278395],
[-105.00183105468751, 39.74613407445653],
[-105.00432014465332, 39.74732195489861]
],[
[-105.00361204147337, 39.74354376414072],
[-105.00301122665405, 39.74278480127163],
[-105.00221729278564, 39.74316428375108],
[-105.00283956527711, 39.74390674342741],
[-105.00361204147337, 39.74354376414072]
]
],[
[
[-105.00942707061768, 39.73989736613708],
[-105.00942707061768, 39.73910536278566],
[-105.00685214996338, 39.73923736397631],
[-105.00384807586671, 39.73910536278566],
[-105.00174522399902, 39.73903936209552],
[-105.00041484832764, 39.73910536278566],
[-105.00041484832764, 39.73979836621592],
[-105.00535011291504, 39.73986436617916],
[-105.00942707061768, 39.73989736613708]
]
]
]
}
This is the actually array of two objects, where the first object has two geometries and the second one. I can access to the geometries of the first object with these queries SELECT AsText( GeometryN( geo_type, 1)) FROM polygon_park; and SELECT AsText( GeometryN( geo_type, 1)) FROM polygon_park; and I get this result
POLYGON((-105.00432014465332 39.74732195489861),(-105.00715255737305 39.7462000683517),(-105.00921249389647 39.74468219277038),(-105.01067161560059 39.74362625960105),(-105.01195907592773 39.74290029616054),(-105.00989913940431 39.74078835902781),(-105.00758171081543 39.74059036160317),(-105.00346183776855 39.74059036160317),(-105.00097274780272 39.74059036160317),(-105.00062942504881 39.74072235994946),(-105.00020027160645 39.74191033368865),(-105.0007152557373 39.74276830198601),(-105.00097274780272 39.74369225589818),(-105.00097274780272 39.74461619742136),(-105.00123023986816 39.74534214278395),(-105.00183105468751 39.74613407445653),(-105.00432014465332 39.74732195489861))
and
POLYGON((-105.00361204147337 39.74354376414072),(-105.00301122665405 39.74278480127163),(-105.00221729278564 39.74316428375108),(-105.00283956527711 39.74390674342741),(-105.00361204147337 39.74354376414072))
, but I do not know how to access to the second object with the following coordinates.
"[-105.00361204147337, 39.74354376414072],
[-105.00301122665405, 39.74278480127163],
[-105.00221729278564, 39.74316428375108],
[-105.00283956527711, 39.74390674342741],
[-105.00361204147337, 39.74354376414072]"
However in both cases I cannot access to the individual points in each geometry.
I need to know this in order to parse this object into json in php.
Thank you a lot in advance!
To access the second object of the first polygon, you use the InteriorRingN(poly, index) where index is 1 based, see the docs for Polygon functions.
So, in your case, you would do:
SELECT AsText( InteriorRingN(GeometryN(geo_type, 1), 1)) FROM polygon_park;
To get individual points use the PointN function of a Linestring. You first have to convert your Polygon rings to Linestrings, for which you can use the Exteriorring or InteriorRingN functions, and then you can access the points.
So, for example, to get the 4th point, of the outer ring of the first polygon, you would do:
SELECT AsText( PointN(ExteriorRing(GeometryN(geo_type, 1)), 4)) FROM polygon_park;
To get the actual values, rather than textual representation, you would use the X and Y functions instead of AsText.
It would possibly have been clearer to use the WKT rather than GeoJSON for you examples, but seeing as there is a one to one mapping between the meaning of parenthesis in WKT and square brackets in GeoJSON, nothing is lost in translation, so to speak.
Related
I have 2 phonograph objects, each one having millions of rows, which I have linked by using the Search Around methods.
On the example below, I filter to an Object Set of Flights based on the departure code, then I Search Around to the Passengers on those flights and then I filter again based on an attribute of Passengers Object.
const passengersDepartingFromAirport = Objects.search()
.flights()
.filter(flight => flight.departureAirportCode.exactMatch(airportCode))
.searchAroundPassengers()
.filter(passenger => passenger.passengerAttribute.exactMatch(value));
The result of the above code is:
LOG [2022-04-19T14:25:58.182Z] { osp: {},
objectSet:
{ objectSetProvider: '[Circular]',
objectSet: { type: 'FILTERED', filter: [Object], objectSet: [Object] } },
objectTypeIds: [ 'passengers' ],
emptyOrderByStep:
{ objectSet: '[Circular]',
orderableProperties:
{ attributeA: [Object],
attributeB: [Object],
attributeB: [Object],
...
Now, when I am trying to use take() or takeAsync() or to aggregate the result using groupBy(), I receive the below error:
RemoteError: INVALID_ARGUMENT ObjectSet:ObjectSetTooLargeForSearchAround with instance ID xxx.
Error Parameters: {
"RemoteError.type": "STATUS",
"objectSetSize": "2160870",
"maxAllowedSize": "100000",
"relationSide": "TARGET",
"relationId": "flights-passengers"
}
SafeError: RemoteError: INVALID_ARGUMENT ObjectSet:ObjectSetTooLargeForSearchAround with instance ID xxx
What could be the way to aggregate or to reduce the result of the above ObjectSet?
The current object storage infrastructure has a limit on the size of the "left side" or "starting object set" for a search around of 100,000 objects.
You can define and object set that uses a search around, which is what you're seeing as the result when you execute the Function before attempting any further manipulations.
Using take() or groupBy "forces" the resolution of the object set definition. I.e. you no longer need the pointer to the objects, but you need to actually materialize some data from each individual object to do that operation.
It's in this materialization step that the limit comes into play - the object sets are resolved and, if the object set at the search around step is larger than 100,000 objects, the request will fail with the above message.
There is ongoing work for Object Storage v2, which will eventually support much larger search-around requests, but for now it's necessary create a query pattern that results in less than 100,000 objects before making a search around.
In some cases it's possible to create an "intermediate" object type that represents a different level of granularity in your data or two invert the direction of your search around to find a way to address these limits.
If you want to stringify column A,B,C for a few rows it makes sense that JSON.stringify returns something like [ ["1a","2a","3a"], ["1b","2b", "3b"] ].
However if you are using just one column i.e. a 1 dimensional array, then what JSON.stringify does is terrible: [ ["1a"], ["1b"] ]
What my API expects is ["1a","1b"]
What I am missing?: How can I tell it to properly format it?
From the question
However if you are using just one column i.e. a 1 dimensional array, then what JSON.stringify does is terrible: [ ["1a"], ["1b"] ]
It looks that you have a misconception, as getValues() returns a bi-dimensional no matter if the range refers to a single row or a single column. Anyway, one way to convert the bi-dimentional array into a one-dimension array is by using Array.prototype.flat().
let column = [[1],[2],[3]]
console.log(column.flat())
I'm starting to explore the JSON1 library for sqlite and have been so far successful in the basic queries I've created. I'm now looking to create a more complicated query that pulls data from multiple levels.
Here's the example JSON object I'm starting with (and most of the data is very similar).
{
"height": 140.0,
"id": "cp",
"label": {
"bind": "cp_label"
},
"type": "color_picker",
"user_data": {
"my_property": 2
},
"uuid": "948cb959-74df-4af8-9e9c-c3cb53ac9915",
"value": {
"bind": "cp_color"
},
"width": 200.0
}
This json object is buried about seven levels deep in a json structure and I pulled it from the larger json construct using an sql statement like this:
SELECT value FROM forms, json_tree(forms.formJSON, '$.root')
WHERE type = 'object'
AND json_extract(value, '$.id') = #sControlID
// In this example, #sControlID is a variable that represents the `id` value we're looking for, which is 'cp'
But what I really need to pull from this object are the following:
the value from key type ("color_picker" in this example)
the values from keys bind ("cp_color" and "cp_label" in this example)
the keys value and label (which have values of {"bind":"<string>"} in this example)
For that last item, the key name (value and label in this case) can be any number of keywords, but no matter the keyword, the value will be an object of the form {"bind":"<some_string>"}. Also, there could be multiple keys that have a bind object associated with them, and I'd need to return all of them.
For the first two items, the keywords will always be type and bind.
With the json example above, I'd ideally like to retrieve two rows:
type key value
color_picker value cp_color
color_picker label cp_label
When I use json_extract methods, I end up retrieving the object {"bind":"cp_color"} from the json_tree table, but I also need to retrieve the data from the parent object. I feel like I need to do some kind of union, but my attempts have so far been unsuccessful. Any ideas here?
Note: if the {"bind":"<string>"} object doesn't exist as a child of the parent object, I don't want any rows returned.
Well, I was on the right track and eventually figured out it. I created a separate query for each of the items I was looking for, then INNER JOINed all the json_tree tables from each of the queries to have all the required fields available. Then I json_extracted the required data from each of the json fields I needed data from. In the end, it gave me exactly what I was looking for, though I'm sure it could be written more efficiently.
For anyone interested, this is what hte final query ended up looking like:
SELECT IFNULL(json_extract(parent.value, '$.type'), '_window_'), child.key, json_extract(child.value, '$.bind') FROM (SELECT json_tree.* FROM nui_forms, json_tree(nui_forms.formJSON, '$') WHERE type = 'object' AND json_extract(nui_forms.formJSON, '$.id') = #sWindowID) parent INNER JOIN (SELECT json_tree.* FROM nui_forms, json_tree(nui_forms.formJSON, '$') WHERE type = 'object' AND json_extract(value, '$.bind') != 'NULL' AND json_extract(nui_forms.formJSON, '$.id') = #sWindowID) child ON child.parent = parent.id;
If you have any tips on reducing its complexity, feel free to comment!
I need to compare duplicates ip of a json by date field and remove the older date
Ex:
[
{
"IP": "10.0.0.20",
"Date": "2019-09-14T20:00:11.543-03:00"
},
{
"IP": "10.0.0.10",
"Date": "2019-09-17T15:45:16.943-03:00"
},
{
"IP": "10.0.0.10",
"Date": "2019-09-18T15:45:16.943-03:00"
}
]
The output of operation need to be like this:
[
{
"IP": "10.0.0.20",
"Date": "2019-09-14T20:00:11.543-03:00"
},
{
"IP": "10.0.0.10",
"Date": "2019-09-18T15:45:16.943-03:00"
}
]
For simplicity's sake, I'll assume the order of the data doesn't matter.
First, if your data isn't already in Python, you can use json.load or json.loads to convert it into a Python object, following the straightforward type mappings.
Then you problem has three parts: comparing date strings as dates, finding the maximum element of a list by that date, and performing this process for each distinct IP address. For these purposes, you can use two of Pyhton's built-in methods and two from the standard library.
Python's built-in max and sorted functions (as well as list.sort) support a (keyword-only) key argument, which uses a function to determine the value to compare by. For example, max(d1, d2, key=lambda x: x[0]) compares the data by the first index of the each (like d1[0] < d2[0]), and returns whichever of d1 and d2 produced the larger key.
To allow that type of comparison between dates, you can use the datetime.datetime class. If your dates are all in the format specified by datetime.datetime.fromisoformat, you can use that function to turn your date strings into datetimes, which can then be compared to each other. Using that in a function that extracts the dates from the dictionaries gives you the key function you need.
def extract_date(item):
return datetime.datetime.fromisoformat(item['Date'])
Those functions allow you to choose the object from the list with the largest date, but not to keep separate values for different IP addresses. To do that, you can use itertools.groupby, which takes a key function and puts the elements of the input into separate outputs based on that key. However, there are two things you might need to watch out for with groupby:
It only groups elements that are next to each other. For example, if you give it [3, 3, 2, 2, 3], it will group two 3s, then two 2s, then one 3 rather than grouping all three 3 together.
It returns an iterator of key, iterator pairs, so you have to collect the results yourself. The best way to do that may depend on your application, but a basic approach is nested iterations:
for key, values in groupby(data, key_function):
for value in values:
print(key, value)
With the functions I've mentioned above, it should be relatively straightforward to assemble an answer to your problem.
I'm using SuperObject to produce JSON. The server I'm working with has some specifications for sorting data results (the fact that this is related to sorting data has nothing to do with my actual question about sorting). The thing is, the server expects these values to be listed in order of how to sort, so for example...
"sort": {
"first_sort_field": 1,
"second_sort_field": 1,
"third_sort_field": -1,
"fourth_sort_field": 1
}
1 means ascending and -1 means descending. But that's not the important part. What's important is that these values in the sort object must be organized in this manner.
To produce this object, I'm doing this:
var
O, O2: ISuperObject;
X: Integer;
//more
begin
O:= SO; //main object
//more
O2:= SO; //sub object
for X := 0 to FSort.Count - 1 do begin
case FSort[X].Direction of
sdAscending: O2.I[FSort[X].FieldName]:= 1;
sdDescending: O2.I[FSort[X].FieldName]:= -1;
end;
end;
O.O['sort']:= O2;
//more
end;
The problem arises when I use SuperObject to serialize this "sort" object. The values seem to be re-arranged, so for example the JSON above would actually come out something like this:
"sort": {
"first_sort_field": 1,
"fourth_sort_field": 1
"second_sort_field": 1,
"third_sort_field": -1,
}
Which is a different order than I intended. This causes the server to return the response data sorted in a different manner than intended.
The question is, how can I make SuperObject serialize the data in the order which I added it rather than its own order? I thought that it might be sorting the values in ABC order, but when combining different types of values (string, integer, object, array, etc.) they're not in ABC order. I'd like to force SuperObject to serialize the data in the order which I added it.
The only solution I can see is to serialize this object manually by concatenating strings. But I'd like to avoid that if at all possible - that's why I'm using SuperObject in the first place.
The documentation for JSON states that its dictionary object is unordered:
An object is an unordered set of name/value pairs. An object begins with { (left brace) and ends with } (right brace). Each name is followed by : (colon) and the name/value pairs are separated by , (comma).
By way of contrast, the JSON array is ordered:
An array is an ordered collection of values. An array begins
with [ (left bracket) and ends with ] (right bracket). Values
are separated by , (comma).
If you want to persist the order of your keys, you will need to do so separately from the dictionary. Any program that expresses meaning by the order in which name/value pairs are written falls outside the JSON spec. So, if your server relies on the order, then that makes the file no longer a JSON file.
Order is clearly important here. And so the solution is clear. Use the ordered data type, the array. Your JSON should be:
"sort": [
{ "name": "first_sort_field", "order": 1 },
{ "name": "second_sort_field", "order": 1 },
.....
]