Re: [OpenMap Users] CSV files and Circles

From: Don Dietrick <dfdietrick_at_gmail.com>
Date: Wed, 10 Sep 2014 12:23:19 -0400

Hey Gary,

I'd check your properties for the fill color. You probably have to do something like 'prefix.location.fillColor'. The javadocs say 'prefix.locationColor' for the line color, but that's outdated (another thing to update) yet works. I looked at the code and it looks like prefix.location.fillColor should work.

There's nothing in OpenMap that will currently do the other thing you are interested in, the union of all the polygons/circles. You could use JTS Topology Suite to create something like that, following a set of steps in the location handler:

- Iterate through the OMGraphicList, grabbing the Shape object from each OMGraphic after it's been generated with a projection.
- With each Shape object, iterate through the points to create a JTS geometry, adding each geometry to a GeometryCollection.
- Iterate through the GeometryCollection to create a Union geometry (see the JTS developer guide, it's pretty straightforward)
- take the Union geometry coordinates, convert them to an array, and then use the projection to inverse project those coordinates to lat/lon space.
- take the inverse projected coordinates and create an OMPoly, or a multi-part OMPoly.

That will get you a unioned object that will reproject itself for different projections, etc. The reason I grab the generated Shape object is because I think JTS works in projected space, it doesn't operate on the great circle lines between the coordinates, so you can get those coordinates from the generated Shape.

Hope this helps,

Don

On Sep 10, 2014, at 11:25 AM, Gary Briggs wrote:

> Oh. That's a bit miserable of them :-(
>
> I really appreciate the work you do on openmap. Between that and SIMDIS,
> pretty much all of my mapping needs nowadays are met.
>
> Two questions have come up regarding my patch:
> * It seems like it's not honoring the fillColor properties. Looking
> on my desktop, I don't think they're being honored by the original
> points, either?
> * Is there a way to convert the circles to nothing-but-their-collective
> outline, rather than all the circles? Something like this:
> http://www.njaudubon.org/portals/10/Oases/Images/nexrads.jpg
> I tried looking on OMGeometry and OMGeometryList to find some sort of
> "derive total outline" or "generate object representing union of these
> other objects", but nothing obvious showed up. Am I missing it?
>
> Thanks!
> Gary
>
> On Wed, Sep 10, 2014 at 10:55:12AM -0400, Don Dietrick wrote:
>> Hi Gary,
>>
>> Google code changed and stopped allowing developers to put zip files on the project's download page. You can grab the latest releases following the links in the narrative. I am going to make a new release shortly (within a week), I need to address a couple of other issues first.
>>
>> - Don
>>
>> On Sep 10, 2014, at 10:47 AM, Gary Briggs wrote:
>>
>>>
>>> Thanks! Are you doing an official release of openmap anytime soon? It
>>> seems like it's up to 5.1.3 in source, but the downloads page only goes
>>> up to 5.0.3
>>>
>>> At work I'm trying to stand up some infrastructure around openmap on an
>>> airgapped network [eg a tile server, shared common resources...], and
>>> it's an easier sell to go with "here's the official build" than "here's
>>> something Gary threw together that has those extra two features we're
>>> all using" :-)
>>>
>>> Have fun,
>>> Gary
>>>
>>>> Cheers,
>>> On Wed, Sep 10, 2014 at 10:28:23AM -0400, Don Dietrick wrote:
>>>> Thanks Gary, I appreciate the patch. Watching you go through this update showed me the flaws in the LocationHandler API, it's not as easily extendable as it could be. It's pretty old, too, so it could use with a refreshing.
>>>>
>>>> - Don
>>>>
>>>> On Sep 7, 2014, at 9:23 PM, Gary Briggs wrote:
>>>>
>>>>> Also, easiest way to test: add a column to cities.csv called
>>>>> "radius". Using tool-of-your-choosing, add a column at the end with a
>>>>> random number in it. There's a sample here:
>>>>> http://icculus.org/~chunky/stuff/cities.csv
>>>>>
>>>>> Add this to openmap.properties:
>>>>> csvcities.circleRadiusIndex=4
>>>>> to check that the unit option it working, simply follow up with another line:
>>>>> csvcities.circleRadiusUnit=NM
>>>>>
>>>>> Cheers,
>>>>> Gary
>>>>>
>>>>> On Sun, Sep 07, 2014 at 09:01:17PM -0400, Gary Briggs wrote:
>>>>>> Hey Don
>>>>>>
>>>>>> Thanks, that's what I was assuming.
>>>>>>
>>>>>> Attached is a patch that does what I need. Hopefully it's adequate to
>>>>>> accept in the base distro. Note that it's purely additive, so even if
>>>>>> circles are added, all other aspects of the file remain the same.
>>>>>>
>>>>>> Cheers,
>>>>>> Gary
>>>>>>
>>>>>> On Sun, Sep 07, 2014 at 06:41:48PM -0400, Don Dietrick wrote:
>>>>>>> Hi Gary,
>>>>>>>
>>>>>>> The OMGraphic you want to use is the OMCircle, created at a lat/lon location with a radius value and a com.bbn.openmap.util.Length object to specify the radius units.
>>>>>>>
>>>>>>> As for extending the CSVLocationHandler, you could do that. You'd want to add your property for the radiusIndex and update the createData() method to use it. You'd also have to get the getTokenDecoder return an object that knows how to create OMCircles using the radiusIndex in the createAndAddObjectFromTokens(). That should do it.
>>>>>>>
>>>>>>> Hope this helps,
>>>>>>>
>>>>>>> Don
>>>>>>>
>>>>>>> On Sep 7, 2014, at 12:51 PM, Gary Briggs wrote:
>>>>>>>
>>>>>>>> Morning,
>>>>>>>>
>>>>>>>> I haven't discovered an existing way to do this in openmap; If I need to
>>>>>>>> implement this myself, I would appreciate a little guidance if possible.
>>>>>>>>
>>>>>>>> Basically, I just want something similar to CSV Location Layer, but with
>>>>>>>> an extra column, "Radius". When radius is specified, a circle is drawn
>>>>>>>> instead of a point, of the world-space radius described in that column. I
>>>>>>>> can't see it currently possible anywhere [since pointRadius/pointOval
>>>>>>>> appear to be in screen-space, and even if they were in world-space,
>>>>>>>> they're fixed for the entire file rather than per-row]
>>>>>>>>
>>>>>>>> Am I missing something obvious?
>>>>>>>>
>>>>>>>> If not, I had several thoughts on how best to implement it, but I wasn't
>>>>>>>> sure what the best way to do it is [where "best" might include "will be
>>>>>>>> accepted as a patch"]:
>>>>>>>> * Modify CSVLocationHandler to include an optional "radiusIndex" parameter
>>>>>>>> * Seems easiest, but looking at the code I'm having a hard time figuring
>>>>>>>> out how I'd do it. It's not clear to me that starting with something
>>>>>>>> that always works with URLRasterLocation is the way to go
>>>>>>>> * Extend CSVLocationHandler, create CSVCircleHandler
>>>>>>>> * Intuitively I might add majorRadius and minorRadius, to make ellipses
>>>>>>>> a "freebie" here.
>>>>>>>> * Create a new handler of sorts
>>>>>>>>
>>>>>>>> I just don't know. I'm still sometimes having a hard time really
>>>>>>>> identifying the flow of data in the code, which is possibly leading me
>>>>>>>> to some confusion too.
>>>>>>>>
>>>>>>>> Cheers,
>>>>>>>> Gary
>>>>>>>>
>>>>>>>> --
>>>>>>>> [To unsubscribe to this list send an email to "majdart_at_bbn.com"
>>>>>>>> with the following text in the BODY of the message "unsubscribe openmap-users"]
>>>>>>
>>>>>> --
>>>>>
>>>>>> diff --git a/src/openmap/com/bbn/openmap/layer/location/csv/CSVLocationHandler.java b/src/openmap/com/bbn/openmap/layer/location/csv/CSVLocationHandler.java
>>>>>> index fb2df41..d36d080 100644
>>>>>> --- a/src/openmap/com/bbn/openmap/layer/location/csv/CSVLocationHandler.java
>>>>>> +++ b/src/openmap/com/bbn/openmap/layer/location/csv/CSVLocationHandler.java
>>>>>> _at_@ -49,10 +49,12 @@ import com.bbn.openmap.layer.location.LocationMenuItem;
>>>>>> import com.bbn.openmap.layer.location.URLRasterLocation;
>>>>>> import com.bbn.openmap.omGraphics.OMGraphic;
>>>>>> import com.bbn.openmap.omGraphics.OMGraphicList;
>>>>>> +import com.bbn.openmap.omGraphics.OMCircle;
>>>>>> import com.bbn.openmap.util.CSVTokenizer;
>>>>>> import com.bbn.openmap.util.DataOrganizer;
>>>>>> import com.bbn.openmap.util.PropUtils;
>>>>>> import com.bbn.openmap.util.quadtree.QuadTree;
>>>>>> +import com.bbn.openmap.proj.Length;
>>>>>>
>>>>>> /**
>>>>>> * The CSVLocationLayer is a LocationHandler designed to let you put data on the
>>>>>> _at_@ -115,6 +117,11 @@ import com.bbn.openmap.util.quadtree.QuadTree;
>>>>>> * csvlocationhandler.defaultIconURL=/data/symbols/default.gif
>>>>>> * # Optional property, if the eastern hemisphere longitudes are negative. False by default.
>>>>>> * csvlocationhandler.eastIsNeg=false
>>>>>> + * # Optional property, if you want a circle around each point, as well as other artifacts. -1 disables, or >=0 to choose a CSV column with radius in it
>>>>>> + * csvlocationhandler.circleRadiusIndex=-1
>>>>>> + * # Optional property. If you want circles, the radius defaults to KM as the units.
>>>>>> + * # Choices are value values in com.bbn.openmap.proj.Length
>>>>>> + * csvlocationhandler.circleRadiusUnit=KM
>>>>>> *
>>>>>> * # CSVLocationHandler has been updated to have regular DrawingAttribute properties for both name and location.
>>>>>> * csvlocationhandler.name.lineColor=FF008C54
>>>>>> _at_@ -159,6 +166,16 @@ public class CSVLocationHandler
>>>>>> */
>>>>>> public static final String NameIndexProperty = "nameIndex";
>>>>>>
>>>>>> + /** Index of column in CSV to use as circle radius */
>>>>>> + protected int circleRadiusIndex = -1;
>>>>>> + /** Property to use to designate the column of the CSV file to use as circle radius */
>>>>>> + public static final String CircleRadiusIndexProperty = "circleRadiusIndex";
>>>>>> +
>>>>>> + /** Units if using circle radius */
>>>>>> + protected Length circleRadiusUnit = Length.KM;
>>>>>> + /** Property to use to designate the column of the CSV file to use as circle radius */
>>>>>> + public static final String CircleRadiusUnitProperty = "circleRadiusUnit";
>>>>>> +
>>>>>> // //////////////////////
>>>>>> // Location Variables
>>>>>>
>>>>>> _at_@ -229,6 +246,21 @@ public class CSVLocationHandler
>>>>>> }
>>>>>>
>>>>>> csvHasHeader = PropUtils.booleanFromProperties(properties, prefix + csvHeaderProperty, false);
>>>>>> + circleRadiusIndex = PropUtils.intFromProperties(properties, prefix + CircleRadiusIndexProperty, -1);
>>>>>> + if(circleRadiusIndex >= 0) {
>>>>>> + // Ignore unit malarkey unless they're actually using circles
>>>>>> + String radiusUnitStr = properties.getProperty(prefix + CircleRadiusUnitProperty);
>>>>>> + if(null != radiusUnitStr) {
>>>>>> + // Check for a valid unit description
>>>>>> + Length testLength = Length.get(radiusUnitStr);
>>>>>> + if(null == testLength) {
>>>>>> + logger.warning("CSVLocationHandler: " + radiusUnitStr
>>>>>> + + " is not a known unit, default to " + circleRadiusUnit.toString());
>>>>>> + } else {
>>>>>> + circleRadiusUnit = testLength;
>>>>>> + }
>>>>>> + }
>>>>>> + }
>>>>>>
>>>>>> if (logger.isLoggable(Level.FINE)) {
>>>>>> logger.fine("CSVLocationHandler indexes:\n latIndex = " + latIndex + "\n lonIndex = " + lonIndex + "\n nameIndex = "
>>>>>> _at_@ -263,6 +295,8 @@ public class CSVLocationHandler
>>>>>> props.put(prefix + LonIndexProperty, (lonIndex != -1 ? Integer.toString(lonIndex) : ""));
>>>>>> props.put(prefix + IconIndexProperty, (iconIndex != -1 ? Integer.toString(iconIndex) : ""));
>>>>>> props.put(prefix + DefaultIconURLProperty, PropUtils.unnull(defaultIconURL));
>>>>>> + props.put(prefix + CircleRadiusIndexProperty, (circleRadiusIndex != -1 ? Integer.toString(circleRadiusIndex) : ""));
>>>>>> + props.put(prefix + CircleRadiusUnitProperty, circleRadiusUnit.getAbbr());
>>>>>>
>>>>>> return props;
>>>>>> }
>>>>>> _at_@ -299,6 +333,8 @@ public class CSVLocationHandler
>>>>>> list.put(IconIndexProperty, "The column index, in the location file, of the icon for locations (optional).");
>>>>>> list.put(DefaultIconURLProperty, "The URL of an image file to use as a default for the location markers (optional).");
>>>>>> list.put(csvHeaderProperty, "Flag to note that the first line in the csv file is a header line and should be ignored.");
>>>>>> + list.put(CircleRadiusIndexProperty, "The column index, in the location file, to use as circle radii (optional).");
>>>>>> + list.put(CircleRadiusUnitProperty, "Short moniker for units of length of circle radius (optional, defaults to KM)");
>>>>>>
>>>>>> return list;
>>>>>> }
>>>>>> _at_@ -466,7 +502,28 @@ public class CSVLocationHandler
>>>>>>
>>>>>> return loc;
>>>>>> }
>>>>>> +
>>>>>> + /**
>>>>>> + * When a new circle object needs to be created from data read in the CSV
>>>>>> + * file, this method is called. This method lets you extend the
>>>>>> + * CSVLocationLayer and easily set what kind of Location objects to use.
>>>>>> + *
>>>>>> + * _at_param lat latitude of location, decimal degrees.
>>>>>> + * _at_param lon longitude of location, decimal degrees.
>>>>>> + * _at_param radius Radius of the circle
>>>>>> + * _at_return graphic object for lat/lon circle.
>>>>>> + */
>>>>>> + protected OMCircle createCircleLocation(float lat, float lon, double radius) {
>>>>>>
>>>>>> + // This will turn into a regular location if iconURL is null.
>>>>>> + OMCircle loc = new OMCircle(lat, lon, radius, circleRadiusUnit);
>>>>>> + getLocationDrawingAttributes().setTo(loc);
>>>>>> +
>>>>>> + logger.fine("CSVLocationHandler " + loc.toString());
>>>>>> +
>>>>>> + return loc;
>>>>>> + }
>>>>>> +
>>>>>> /**
>>>>>> * _at_param ranFile the file to be read. The file pointer should be set to the
>>>>>> * line you want read.
>>>>>> _at_@ -646,6 +703,7 @@ public class CSVLocationHandler
>>>>>> protected String name;
>>>>>> protected float lat;
>>>>>> protected float lon;
>>>>>> + protected float circleRadius;
>>>>>> protected String iconURL;
>>>>>>
>>>>>> public DefaultLocationDecoder() {
>>>>>> _at_@ -655,6 +713,7 @@ public class CSVLocationHandler
>>>>>> name = null;
>>>>>> lat = 0f;
>>>>>> lon = 0f;
>>>>>> + circleRadius = 1f;
>>>>>> iconURL = null;
>>>>>> }
>>>>>>
>>>>>> _at_@ -674,6 +733,8 @@ public class CSVLocationHandler
>>>>>> }
>>>>>> } else if (i == iconIndex) {
>>>>>> iconURL = (String) token;
>>>>>> + } else if (i == circleRadiusIndex) {
>>>>>> + circleRadius = ((Double) token).floatValue();
>>>>>> }
>>>>>> }
>>>>>>
>>>>>> _at_@ -681,10 +742,15 @@ public class CSVLocationHandler
>>>>>> if (iconURL == null && defaultIconURL != null) {
>>>>>> iconURL = defaultIconURL;
>>>>>> }
>>>>>> -
>>>>>> +
>>>>>> + if(circleRadiusIndex > -1) {
>>>>>> + OMCircle circle = createCircleLocation(lat, lon, circleRadius);
>>>>>> + organizer.put(lat, lon, circle);
>>>>>> + }
>>>>>> +
>>>>>> Location loc = createLocation(lat, lon, name, iconURL);
>>>>>> -
>>>>>> organizer.put(lat, lon, loc);
>>>>>> +
>>>>>> reset();
>>>>>> }
>>>>>>
>>>>>
>>>>>
>>>>> --
>>>
>>> --
>
> --

--
[To unsubscribe to this list send an email to "majdart_at_bbn.com"
with the following text in the BODY of the message "unsubscribe openmap-users"]
Received on Wed Sep 10 2014 - 12:25:31 EDT

This archive was generated by hypermail 2.3.0 : Tue Mar 28 2017 - 23:25:10 EDT