3

I apologize for what is, I'm sure, a very village-idiot question, but I think my question is simply too dumb for the answers I've found on this subject.

I've used QGIS to save a shapefile (.shp) file as .kml, then used OpenLayers to import it as a OpenLayers.Vector.Layer.

The .kml file consists of a very long series of placemarks like the one shown below.

<?xml version="1.0" encoding="utf-8" ?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document><Folder><name>events_a_</name>
  <Placemark>
    <ExtendedData><SchemaData schemaUrl="#events_a_">
        <SimpleData name="Date">2001-04-15</SimpleData>
        <SimpleData name="Latitude">34.683300000000003</SimpleData>
        <SimpleData name="Longitude">-76.666700000000006</SimpleData>
        <SimpleData name="state">North Carolina</SimpleData>
        <SimpleData name="type">Seizure</SimpleData>
        <SimpleData name="total regs">1.000000000000000</SimpleData>
        <SimpleData name="gtycode1">2335384</SimpleData>
        <SimpleData name="final_date">2005/06/28</SimpleData>
        <SimpleData name="end_date">2005-06-29</SimpleData>
    </SchemaData></ExtendedData>
  <Point><coordinates>-76.6667,34.6833</coordinates></Point>
  </Placemark>

I add this this file as an OpenLayers.Vector thusly:

var cwevents = new OpenLayers.Layer.Vector('KML', {
        strategies:[new OpenLayers.Strategy.Fixed()],
        protocol: new OpenLayers.Protocol.HTTP({
            url: './events_kml/civwar_events(a).kml',
            format: new OpenLayers.Format.KML({
                extractStyles: false,
                extractAttributes: true,
                maxDepth: 2
            })
        })
    });      

My problem is that attributes whose type I need to be numeric (or datetime) keep being loaded as simple string variables. ('total_regs' will load as ' "2.0000" ' rather than ' 2.000 ' .) This has made it impossible, for example, for me to vary a feature's marker size according to the value of one of its numeric attributes.

So would be extremely grateful for any of the following:

  1. How to ensure that OpenLayers loads specific vector feature attributes as a specified data type.
  2. How to change the KML file so that Openlayers is in no doubt about the data type of individual feature attributes.List item
  3. Any other approach that might help me here.

    Apologies again for an extremely primitive question, but quite new at OpenLayers, and this problem has stalled me for a ridiculously long amount of time.

SECOND UPDATE: The KML sample file supplied by @user30184 in the answer below might be a quickest way of isolating whatever obvious thing I'm failing to do in OpenLayers.

If anyone can add this kml file as a vector layer to an OpenLayers map, with the "b" and "c" attributes being correctly read-in as a numeric data type (int, float, anything) rather than as string, I would be very grateful to see the javascript you used to add the layer.

One last note: the way I added the layer (in the second code block above) has been essentially the same one I've found in the examples in two books and the web. The only variations have been to properties or strategies ("maxDepth:", "extractStyles", "strategies:") that have no effect on the correctly importing the data type.

Alternatively, if someone knows of a vector-layer format (geojson?) where this problem definitely does not occur, do please let me know: might be the most efficient way of solving this. Thanks again.

  • I guess you must use SimpleFields and define the type in schema as in developers.google.com/kml/documentation/kmlreference#schema. – user30184 Sep 23 '14 at 13:49
  • Thanks for replying, @user30184 . I think I tried doing following your suggestion (see "UPDATE"). No change, but do let me know if I tripped up somewhere. – claud alexander Sep 24 '14 at 5:30
  • Perhaps some of number data might be interpreted as string in your dataset.It could be the reason that QGIS or OGR may evaluate the field as string.Can you check variety of your data ? – Myra Sep 24 '14 at 13:18
1

I created a shapefile with attributes of type string, integer, double, and date. Then I converted the shapefile into KML with GDAL 2.0-dev version.

ogr2ogr -f kml type.kml typetest.shp

Resulting KML file contains schema definitions in the end of the file.

<?xml version="1.0" encoding="utf-8" ?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document><Folder><name>typetest</name>
  <Placemark>
    <ExtendedData><SchemaData schemaUrl="#typetest">
        <SimpleData name="a">as</SimpleData>
        <SimpleData name="b">1</SimpleData>
        <SimpleData name="c">34.5600000000000020</SimpleData>
        <SimpleData name="d">2012/06/12</SimpleData>
    </SchemaData></ExtendedData>
      <Point><coordinates>87,19</coordinates></Point>
  </Placemark>
  <Placemark>
    <ExtendedData><SchemaData schemaUrl="#typetest">
        <SimpleData name="a">df</SimpleData>
        <SimpleData name="b">2</SimpleData>
        <SimpleData name="c">12.9800000000000000</SimpleData>
        <SimpleData name="d">2012/06/12</SimpleData>
    </SchemaData></ExtendedData>
      <Point><coordinates>136,59</coordinates></Point>
  </Placemark>
  <Placemark>
    <ExtendedData><SchemaData schemaUrl="#typetest">
        <SimpleData name="a">fg</SimpleData>
        <SimpleData name="b">3</SimpleData>
        <SimpleData name="c">12.5600000000000000</SimpleData>
        <SimpleData name="d">2012/06/12</SimpleData>
    </SchemaData></ExtendedData>
      <Point><coordinates>165,21</coordinates></Point>
  </Placemark>
</Folder>
<Schema name="typetest" id="typetest">
    <SimpleField name="a" type="string"></SimpleField>
    <SimpleField name="b" type="float"></SimpleField>
    <SimpleField name="c" type="float"></SimpleField>
    <SimpleField name="d" type="string"></SimpleField>
</Schema>
</Document></kml>

Integers and doubles are both advertised as "float" but they are numbers anyhow and GDAL itself can resolve the schema when I tested it with ogrinfo.

I suppose that QGIS creates similar KML. Check with ogr2ogr if it shows data types correctly. If it does there is probably nothing wrong with your KML and you can concentrate on how OpenLayers can be made to resolve the schema.

  • Thanks for the ogr2ogr command and the test KML, @user30184. The problem definitely seems to be that I'm missing something on the OpenLayers side. Not only was I unable to solve the attribute-type problem with my own data, but the problem persists even if I simply try to load the KML you wrote above. – claud alexander Sep 25 '14 at 2:00
  • To be a little more constructive, if anyone reading this is able successfully to load @user30184 's kml file above as a vector layer in OpenLayers, with the attributes loading as a numeric type, please let me know, because there's clearly something I'm not doing in my script. – claud alexander Sep 25 '14 at 2:05
0

OK, figured it out: it was indeed both an OpenLayers- as well as I'm-an-idiot thing.

I was fretting about strings and floats because I was trying to make the radius of circle-markers proportional to an attribute value in my kml layer's features. The OpenLayers tutorial examples I was following all used toy vector layers added manually as part of the map's html, where the numeric values were indeed entered and were returned (when you looked them up in the Firebug console) as numbers. This made it simple, in these examples, to say that all you needed to do was to a style map with something like, in my case, 'pointRadius: "${total_regs}"' .

Now, when I tried this no markers were returned at all, and, as near as I could see it, this was because, instead of those nice unquotation-marked numbers I saw in the examples, my map was loading the total_regs feature attribute as a string. I then proceeded to waste a bunch of time trying to use for-loops to pass these attributes thru' a javascript Number(), before I decided to waste other people's time by asking the question on this website.

I found the solution while looking up the posts on the "related questions" sidebar. It's here, openlayers attribute substitution failing on kml file , with the stone that slew Goliath being this:

The MILE attribute is an object Object { value="3", displayName="MILE"}
So try doing something like 'label': '${MILE.value}',

Not terribly mysterious, I suppose, but, if anyone's planning to do an OpenLayers tutorial, I might suggest that there's a market for styling examples that load external data rather than, to quote two otherwise really excellent introductory books:

In addition, we are setting in each feature, a couple of attributes (radius and temp)  with random values:

    // Add random attributes
    var radius = Math.round(Math.random() * 15 + 4);
    var temp = Math.round(Math.random() * 4);
    pointFeature.attributes.radius = radius;
    pointFeature.attributes.temp = temp;

or

Let's demonstrate how to use attribute replacement to change the style of features based on their attribute.

Make a copy of the previous example. We'll be changing it slightly to demonstrate attribute replacement. To do so, we'll first need to give our features some attributes that we can access. Modify the addFeature code in the for loop to add attributes as follows:

for(var i=0; i<10; i++){ 
    vector_layer.addFeatures([new OpenLayers.Feature.Vector( 
        new OpenLayers.Geometry.Point( 
            (Math.floor(Math.random() * 360) - 180), 
            (Math.floor(Math.random() * 180) - 90) 
        ), 
        { 
            //Attributes go here 
            size: 5 + (Math.floor(Math.random() * 20)), 
            label: 'F' + i, 
            strokeWidth: (Math.floor(Math.random() * 10)) 
        } 
    )]); 
}

Now, we just need to modify the vector_style style object to include attribute replacements so we can use the size, label, and strokeWidth properties of the features we just created.

I suspect I'll be running into problems when I start fooling around with date data, but by then hopefully I'll be able at least to ask the right question, and not waste quite as much of other people's time as I've done in this case. Many, many thanks to all.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.