After successfully writing M values into a shapefile (.shp, only points for now), I now also want to read the generated file and print the full coordinate set (x, y, z and m) using geotools (23-SNAPSHOT).

I found two different ways to do it (see code below) but both only give me a normal Coordinate object that has an M attribute, which is always NaN. I know that writing the file was successful because QGIS can see the full coordinates (including M).

How do I read the file, while still getting the actual M values?

Code I've tested:

1.From official website:

File f = new File(path);
Map<String, Object> map = new HashMap<String, Object>();

try {
    map.put("url", f.toURI().toURL());
    DataStore dataStore = DataStoreFinder.getDataStore(map);
    String typeName = dataStore.getTypeNames()[0];

    FeatureSource<SimpleFeatureType, SimpleFeature> source = dataStore.getFeatureSource(typeName);
    Filter filter = Filter.INCLUDE; // ECQL.toFilter("BBOX(THE_GEOM, 10,20,30,40)")    
    FeatureCollection<SimpleFeatureType, SimpleFeature> collection = source.getFeatures(filter);
    FeatureIterator<SimpleFeature> features = collection.features();

    while(features.hasNext()) {
        SimpleFeature feature = features.next();
        List attributes = feature.getAttributes();
        Collection properties = feature.getProperties();

        if(attributes.get(0) instanceof Point) {
            Point p = (Point) attributes.get(0);
            Coordinate c = p.getCoordinate(); //"c.getM()" returns "NaN"
            CoordinateXYZM cxyzm = new CoordinateXYZM(c); //"cxyzm.getM()" returns "0.0"
} catch (Exception e) {
    System.out.println("Exception: "+e);

2.From a question here on Stackexchange:

File f = new File(path);

try {
    FileDataStore store = FileDataStoreFinder.getDataStore(f);
    SimpleFeatureSource featureSource = store.getFeatureSource();
    SimpleFeatureCollection featureCollection = featureSource.getFeatures();
    SimpleFeatureIterator it = featureCollection.features();

        SimpleFeature feat = it.next();
        Geometry g = (Geometry) feat.getDefaultGeometry(); //"org.locationtech.jts.geom.Geometry", NOT "org.opengis.geometry.Geometry"!
        Coordinate c = g.getCoordinate(); //"c.getM()" returns "NaN"
        CoordinateXYZM cxyzm = new CoordinateXYZM(c); //"cxyzm.getM()" returns "0.0"
} catch (IOException e) {
    System.out.println("Exception: "+e);

1 Answer 1


From a quick look at the ShapeFile reading code it appears that GeoTools just reads the M value and throws it away. So it looks like what you are trying to do is impossible.

I haven't tested it but if you change line 89 to

cs.setOrdinate(0, CoordinateSequence.M,  buffer.getDouble());

it should work. If you test this and it does work please make a PR for future users.

  • Thanks for your reply! That's a pity! :/ I'm currently trying to clone it from Git but it's not going well, so I'm not sure when and if I'll be able to try it.
    – Neph
    Sep 5, 2019 at 14:26
  • at least make an enhancement request at osgeo-org.atlassian.net/projects/GEOT/issues and someone may look at it in the next sprint
    – Ian Turton
    Sep 5, 2019 at 15:04
  • I opened an issue.
    – Neph
    Sep 6, 2019 at 10:49

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.