ObjectScript ListOfObjects to 2D Python array
My general question is how to convert to a %Library.ListOfObjects to a Python "array-like" structure for use in Matplotlib.
Specifically, I have a Line Object which is comprised of a list of Points (see classes below). I want to pass the line to Python to create a Matplotlib Path
.
Bonus points for converting the Point to a Python tuple!
Class geo.model.Point Extends %SerialObject
{
Property latitude As %Float(MAXVAL = 90.0, MINVAL = -90.0, SCALE = 6);
Property longitude As %Float(MAXVAL = 180.0, MINVAL = -180.0, SCALE = 6);
}
Class geo.model.Line Extends %SerialObject
{
Property points As list Of geo.model.Point;
}
Product version: IRIS 2022.3
Easiest way would be to add %JSON.Adapter and use JSON for interop.
That would certainly work, but my use case is geographic data and a natural feature (e.g. a river or a coastline) could be composed of thousands of Points, so I want something more performance-oriented than JSON.
Project the list of
geo.model.Point
as a separate table:Class geo.model.Line Extends %Persistent { Property points As list Of geo.model.Point(SQLPROJECTION = "table/column"); }
And you can use SQL query (via
iris.sql
) to get all points in line:SELECT points_latitude, points_longitude FROM geo_model.Line_points WHERE Line = ? ORDER BY element_key
If you have thousands of points that would likely be the fastest way to transfer (barring callin/callout shenanigans).
have you tired this python module ?
it can convert $list to python list.
Great @Guillaume Rongier ! Do you have an example code?
of course he does! https://github.com/grongierisc/iris-dollar-list#12-usage
Also on OEX
Hi @Guillaume Rongier I can't use that because my Points are floats and iris-dollar-list doesn't support floats yet?
Hi @Raj Singh , it does support float even is the readme is not up to date.
If you are looking for an objectscript / embedded python approach Alex Woodhead solution will fit you well.
If you are looking for an python only approach my module may help you.
I made a utility for converting between Cache Lists and Arrays with Python Lists and Dictionaries.
Bi-directional. Ensures the keys are strings when going from Array keys to Dictionary keys.
https://github.com/alexatwoodhead/PyNow/blob/main/Py.Helper.xml
Also have an approach for storing (pickle) and retrieving Numpy arrays in IRIS Property Streams if that is of use.
Using the the handy utility from @Alex Woodhead I was able to get something working. As of now you can get the Point, Line and Polygon code from https://github.com/isc-rsingh/spatialiris but I can't guarantee those classes won't change in the future. I include demo code here to show:
Class geo.ToolsExample Extends %RegisteredObject { ClassMethod createPolygon() As geo.model.Polygon { set l = ##class(geo.model.Line).%New() do l.addPoint(##class(geo.model.Point).%New(0.01,0.01)) do l.addPoint(##class(geo.model.Point).%New(2.01,0.01)) do l.addPoint(##class(geo.model.Point).%New(2.01,2.01)) do l.addPoint(##class(geo.model.Point).%New(0.01,2.01)) do l.addPoint(##class(geo.model.Point).%New(0.01,0.01)) set polygon = ##class(geo.model.Polygon).%New() set polygon.line = l Return polygon } ClassMethod test() { set polygon = ..createPolygon() set isin = ..PointInPolygon(polygon, ##class(geo.model.Point).%New(1.01,1.01)) w isin,! set isout = ..PointInPolygon(polygon, ##class(geo.model.Point).%New(3.01,3.01)) w isout,! } ClassMethod PointInPolygon(poly As geo.model.Polygon, pt As geo.model.Point) As %Boolean { set mp = ##class(%SYS.Python).Import("matplotlib") set mpltPath = mp.path set polylist = poly.getAsList() set nothing = ##class(Py.Helper).toPyListOrString(polylist,.poly2) set point = ##class(Py.Helper).toPyListOrString(pt.getAsList()) set path = ..invoke(mpltPath,poly2) Return path."contains_point"(point) } ClassMethod invoke(ByRef mpltPath As %SYS.Python, ByRef poly2) As %SYS.Python [ Language = python ] { return mpltPath.Path(poly2) } }
Well done @Raj Singh - thank you for sharing your solution with the Community!
💡 This question is considered a Key Question. More details here.