On Fri, Aug 14, 2026 at 5:58 AM <[email protected]> wrote:

> Send gdal-dev mailing list submissions to
>         [email protected]
>
> To subscribe or unsubscribe via the World Wide Web, visit
>         https://lists.osgeo.org/mailman/listinfo/gdal-dev
> or, via email, send a message with subject or body 'help' to
>         [email protected]
>
> You can reach the person managing the list at
>         [email protected]
>
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of gdal-dev digest..."
>
>
> Today's Topics:
>
>    1. Re: AutoIdentifyEPSG() fails on standard ESRI-dialect
>       NAD83/UTM .prj (proj_identify succeeds); FindMatches() also
>       missing from Java bindings (Barry DeZonia)
>
>
> ----------------------------------------------------------------------
>
> Message: 1
> Date: Thu, 13 Aug 2026 19:28:00 -0500
> From: Barry DeZonia <[email protected]>
> To: Tom Moore <[email protected]>
> Cc: Even Rouault <[email protected]>,
>         [email protected]
> Subject: Re: [gdal-dev] AutoIdentifyEPSG() fails on standard
>         ESRI-dialect NAD83/UTM .prj (proj_identify succeeds); FindMatches()
>         also missing from Java bindings
> Message-ID:
>         <CAKcvfuT0AFzHboG8uiWwkGZ6MowhfjUUtQZPB4gvBmeX=
> [email protected]>
> Content-Type: text/plain; charset="utf-8"
>
> One maybe nonsense question: where does panConfidence4 come from? Are you
> using an undeclared variable?
>
> On Thu, Aug 13, 2026 at 7:24?PM Barry DeZonia <[email protected]> wrote:
>
> > My foggy memory tells me that this looks good. I will let you and
> > Even figure out the PR issue.
> >
> > On Thu, Aug 13, 2026 at 6:56?PM Tom Moore <[email protected]> wrote:
> >
> >> Thanks for offering to take a look.  I have a working draft already, but
> >> I'm not sure if I'm taking the right approach and could use a review.
> >>
> >> The signature translation itself is the easy part.  The C# binding in
> >> osr.i was an almost perfect example, and this is what I changed it to:
> >>
> >>     #ifdef SWIGJAVA
> >>       OSRSpatialReferenceShadow** FindMatches( char** options, int*
> >> nvalues, int** confidence_values )
> >>       {
> >>            return (OSRSpatialReferenceShadow**) OSRFindMatches(self,
> >> options, nvalues, confidence_values);
> >>       }
> >>     #endif
> >>
> >> Everything interesting (haha, challenging) turned out to be in
> >> typemaps_java.i, getting SWIG to actually expose that return value and
> the
> >> two output parameters sensibly in Java.  I haven't used swig in a long
> >> time, so I had forgotten most of the incantations.  Llm to the rescue.
> >>
> >> Here is the addition to typemaps_java.i:
> >> == start ==
> >> %typemap(in,numinputs=0) int* nvalues (int nMatches = 0)
> >> {
> >>   /* %typemap(in,numinputs=0) int* nvalues */
> >>   $1 = &nMatches;
> >> }
> >>
> >> %typemap(in) int** confidence_values (int* panConfidence = NULL)
> >> {
> >>   /* %typemap(in) int** confidence_values. Ignore the input,
> >>      keep $input around so argout can write the real
> >>      result into element [0]. */
> >>   $1 = &panConfidence;
> >> }
> >>
> >> %typemap(argout) int** confidence_values
> >> {
> >>   /* %typemap(argout) int** confidence_values will fill the caller's
> >> int[][] */
> >>   if ($input && jenv->GetArrayLength($input) >= 1) {
> >>     jintArray confArray = jenv->NewIntArray(nMatches3);
> >>     jenv->SetIntArrayRegion(confArray, 0, nMatches3,
> >> (jint*)panConfidence4);
> >>     jenv->SetObjectArrayElement($input, 0, confArray);
> >>     jenv->DeleteLocalRef(confArray);
> >>   }
> >>   CPLFree(panConfidence4);
> >> }
> >>
> >> %typemap(jni) int** confidence_values "jobjectArray"
> >> %typemap(jtype) int** confidence_values "int[][]"
> >> %typemap(jstype) int** confidence_values "int[][]"
> >> %typemap(javain) int** confidence_values "$javainput"
> >>
> >> %typemap(out) (OSRSpatialReferenceShadow**)
> >> {
> >>   const jclass srsClass =
> >> jenv->FindClass("org/gdal/osr/SpatialReference");
> >>   const jmethodID srsCtor = jenv->GetMethodID(srsClass, "<init>",
> >> "(JZ)V");
> >>
> >>   jresult = jenv->NewObjectArray(nMatches3, srsClass, NULL);
> >>   for (int i = 0; i < nMatches3; i++) {
> >>     OSRReference(result[i]);
> >>     jobject srsObj = jenv->NewObject(srsClass, srsCtor,
> (jlong)result[i],
> >> (jboolean)true);
> >>     jenv->SetObjectArrayElement(jresult, i, srsObj);
> >>     jenv->DeleteLocalRef(srsObj);
> >>   }
> >>   OSRFreeSRSArray(result);
> >> }
> >>
> >> %typemap(jni) OSRSpatialReferenceShadow** "jobjectArray"
> >> %typemap(jtype) OSRSpatialReferenceShadow**
> >> "org.gdal.osr.SpatialReference[]"
> >> %typemap(jstype) OSRSpatialReferenceShadow**
> >> "org.gdal.osr.SpatialReference[]"
> >> %typemap(javaout) OSRSpatialReferenceShadow** {
> >>     return $jnicall;
> >>   }
> >> == end ==
> >>
> >> The nvalues argument stays hidden (numinputs=0), while confidence_values
> >> becomes visible as an int[][] out-box, following the same
> >> caller-passes-a-1-element-array-and-we-fill-it idiom already used
> elsewhere
> >> in typemaps_java.i (the GDALDimensionHS** pattern was the model here).
> >>
> >> SWIG auto-suffixes typemap-declared local variables with the argument's
> >> position in the full parameter list to avoid collisions.  FOr example, a
> >> variable I declared as (int nMatches = 0) inside the nvalues typemap
> >> (argument position 3) actually gets emitted into the generated code as
> >> nMatches3, not nMatches. This isn't visible from the .i source at all, I
> >> only found it by examining the generated osr_wrap.cpp after a failed
> >> compile. Any other typemap block that needs to reference that same
> variable
> >> (the argout/out blocks) has to hardcode the anticipated suffixed name
> >> directly because SWIG doesn't rewrite references for you.
> >>
> >> End result:
> >>
> >>     public SpatialReference[] FindMatches(Vector options, int[][]
> >> confidenceValuesOut)
> >>
> >> The function returns an array of matches (SpatialReference[] as
> >> OSRSpatialReferenceShadow**), which is the primary thing that you want
> to
> >> get from this function.
> >>
> >> How to use:
> >>     int[][] confidence = new int[1][];
> >>     SpatialReference[] matches = srs.FindMatches(null, confidence);
> >>     int[] confidenceValues = confidence[0];
> >>
> >> Patched against the current master.  Tested on against an esri shapefile
> >> .prj (ESRI-dialect NAD83 / UTM zone 11N WKT) that AutoIdentifyEPSG()
> fails
> >> on with 'Unsupported SRS' -- FindMatches() correctly returns a single
> >> match, EPSG:26911, with confidence[0][0] = 100, matching projinfo
> >> --identify exactly on the same input.  Not tested any further than that.
> >>
> >> How does this look so far?  Is this going in the right direction?  If
> so,
> >> what would it take to turn this into an acceptable PR?
> >>
> >> Thanks again for your help, and full disclosure, thanks to llm for
> >> significant assistance on this.
> >> Tom
> >>
> >> On Thu, Aug 13, 2026, at 5:16 PM, Barry DeZonia wrote:
> >>
> >> AI is helping me remember
> >>
> >> for the FindMatches() routine would you want it matching as close as
> >> possible C types or would you want a simplified API for Java that mogt
> >> communicate info via an array of strings (or one formatted string).
> Sorry
> >> if that sounds out of left field.
> >>
> >> One AI said this:
> >> 2. Handle Java JNI Typemaps
> >> Because int** and object arrays (OSRSpatialReferenceShadow***) do not
> >> map cleanly to standard Java types, you must ensure your SWIG
> configuration
> >> or a companion helper helper translates them into manageable objects on
> the
> >> Java side.
> >> Alternatively, if dealing with direct pointer manipulation via SWIG
> >> typemaps is too complex, developers routinely implement a *custom C++
> >> wrapper function* inside osr.i that bundles the results into a string
> >> format (such as an array of matching EPSG strings and confidences)
> before
> >> passing it over the JNI boundary:
> >>
> >> swig
> >>
> >> %extend OSRSpatialReferenceShadow {
> >>     // A simplified wrapper returning matches as formatted string
> arrays to avoid pointer hell
> >>     char** FindMatchesSimple(char** options) {
> >>         int nEntries = 0;
> >>         int* panConfidence = NULL;
> >>         OGRSpatialReferenceH* pahSRS =
> OGRSpatialReference_FindMatches(self, options, &nEntries, &panConfidence);
> >>
> >>         char** papszResult = NULL;
> >>         // Construct a structured string array containing
> "EPSG:Code,Confidence"
> >>         for(int i = 0; i < nEntries; i++) {
> >>             const char* pszAuthName =
> OGRSpatialReference_GetAttrValue(pahSRS[i], "AUTHORITY", 0);
> >>             const char* pszAuthCode =
> OGRSpatialReference_GetAttrValue(pahSRS[i], "AUTHORITY", 1);
> >>             // Format string logic, append to papszResult...
> >>             // BDZ - TODO - NOTE - This is the real work needed to
> finish this method.
> >>         }
> >>
> >>         OSRFreeSRSArray(pahSRS);
> >>         CPLFree(panConfidence);
> >>         return papszResult;
> >>     }
> >> }
> >>
> >>
> >> On Thu, Aug 13, 2026 at 3:08?PM Barry DeZonia <[email protected]>
> wrote:
> >>
> >> I could maybe help here but, good god, it's been a long time since I've
> >> worked on the Java bindings and I remember almost nothing. Maybe if I
> >> inspect the Java bindings code I will remember some stuff. Naively, the
> >> function signature looks pretty simple to translate.
> >>
> >> On Thu, Aug 13, 2026 at 6:53?AM Even Rouault via gdal-dev <
> >> [email protected]> wrote:
> >>
> >>
> >> Tom,
> >>
> >> yes FindMatches() is what is needed for your use case and it is not
> >> currently available in the Java bindings. That would require someone to
> >> write the appropriate typemap(s) to map the C types to Java types.
> >>
> >> Even
> >> Le 13/08/2026 ? 13:15, Tom Moore via gdal-dev a ?crit :
> >>
> >> Hi all,
> >>
> >> I'm running into a case where SpatialReference.AutoIdentifyEPSG() fails
> >> on a completely standard, well-formed ESRI-dialect .prj file, even
> though
> >> the underlying PROJ identification machinery (proj_identify(), as
> exercised
> >> via "projinfo --identify") resolves it correctly with 100% confidence.
> I'd
> >> like to know whether this is a known limitation, and whether there's a
> >> recommended workaround for Java bindings users specifically, since
> >> FindMatches() isn't exposed there.
> >>
> >> Environment:
> >> - GDAL 3.11.1 (Windows build)
> >> - PROJ 9.6.2
> >> - Java bindings (org.gdal.osr / SWIG)
> >>
> >> Input WKT (contents of a shapefile .prj, ESRI dialect):
> >>
> >>
> >>
> PROJCS["NAD_1983_UTM_Zone_11N",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",-117.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]
> >>
> >> QGIS correctly identifies this as EPSG:26911.
> >>
> >> What I tried (Java):
> >>
> >>     SpatialReference srs = new SpatialReference();
> >>     srs.ImportFromESRI(lines);   // also tried plain ImportFromWkt() but
> >> got the same result
> >>     srs.SetAxisMappingStrategy(osrConstants.OAMS_TRADITIONAL_GIS_ORDER);
> >>
> >>     try {
> >>         srs.AutoIdentifyEPSG();
> >>     } catch (Exception ex) {
> >>         System.out.println("Exception: " + ex.getMessage());
> >>     }
> >>     System.out.println("code = " + srs.GetAuthorityCode(null));
> >>
> >> Result:
> >>
> >>     Exception: OGR Error: Unsupported SRS
> >>     code = null
> >>
> >> gdal.GetLastErrorType() / GetLastErrorMsg() are empty.  No additional
> >> diagnostic detail is surfaced beyond the generic exception.
> >>
> >> I ruled out several things before suspecting this is a
> AutoIdentifyEPSG()
> >> limitation rather than an environment/config issue on my end:
> >>
> >> 1. proj.db itself is correct.  Confirmed by mounting the exact same
> >> proj.db (from the PROJ 9 data directory used by my JAva app) into a
> clean
> >> ghcr.io/osgeo/gdal:ubuntu-small-latest container and running
> >> `gdalsrsinfo -e` against the same .prj file. It resolved to EPSG:26911
> >> correctly, full WKT2 with all authority IDs.
> >> 2. PROJ_LIB / PROJ_DATA environment variables are set correctly and
> >> confirmed using System.getenv() to be visible to the process
> >> 3. Tried MorphFromESRI() (both via ImportFromESRI() alone, and combined
> >> with an explicit MorphFromESRI() call) - no change.
> >> 4. Tried explicit SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER)
> >> before calling AutoIdentifyEPSG() - no change.
> >> 5. Ran the projinfo.exe from the gdal build that I am using with the
> Java
> >> app directly against the same .prj file:
> >>
> >>     projinfo.exe --identify fmu.prj
> >>     ...
> >>     Identification match count: 1
> >>     EPSG:26911: 100 %
> >>
> >> So proj_identify() / FindMatches()-equivalent logic resolves this WKT
> >> perfectly in the exact same native build, but AutoIdentifyEPSG() fails
> on
> >> it.
> >>
> >> This looks consistent with a few things I found in the tracker/mailing
> >> list archives while investigating:
> >>
> >> - https://trac.osgeo.org/gdal/ticket/6188 -- maintainer comment noting
> >> AutoIdentifyEPSG() has "very limited capabilities" and would need fuzzy
> >> matching to handle inexact datum/ellipsoid names, "especially when
> dealing
> >> with WKT coming from ESRI."
> >> - https://github.com/OSGeo/gdal/issues/4038 -- near-identical repro WKT
> >> (ESRI-dialect UTM), with a maintainer noting AutoIdentifyEPSG() can
> return
> >> OGRERR_UNSUPPORTED_SRS while having still injected partial AUTHORITY
> tags
> >> into sub-nodes.  This matches what I see when printing the WKT after the
> >> failed call (DATUM gets EPSG:6269, but the top-level PROJCS never gets
> >> an ID).
> >> - https://github.com/OSGeo/gdal/issues/2303 -- shows the standard
> Python
> >> workaround (fall back to FindMatches() when AutoIdentifyEPSG() fails),
> >> which leads to my second question below.
> >>
> >> Questions:
> >>
> >> 1. Is AutoIdentifyEPSG() failing on this ESRI-dialect NAD83/UTM WKT a
> >> known limitation, or does this look like a genuine regression/bug worth
> >> filing?
> >> 2. FindMatches() does not appear to be exposed in the Java SWIG bindings
> >> (org.gdal.osr.SpatialReference).  Is that correct, or am I missing
> >> something? If it's genuinely absent, is there any appetite for adding
> it,
> >> given it's the documented fallback for exactly this situation in other
> >> language bindings?
> >> 3. Short of shelling out to "projinfo --identify" as a subprocess, is
> >> there a recommended in-process approach for Java bindings users to reach
> >> the same identification logic?
> >>
> >> Happy to provide a minimal reproducible test case / file a tracker issue
> >> if that's useful, but I wanted to check here first in case this is
> already
> >> understood behavior.
> >>
> >> Thanks,
> >> Tom
> >>
> >>
> >> _______________________________________________
> >> gdal-dev mailing [email protected]://
> lists.osgeo.org/mailman/listinfo/gdal-dev
> >>
> >> -- http://www.spatialys.com
> >> My software is free, but my time generally not.
> >> LLMs contribute to global warming and brain rot.
> >> Let's guillotine them! "Ah ! ?a ira, ?a ira, ?a ira !"
> >>
> >> _______________________________________________
> >> gdal-dev mailing list
> >> [email protected]
> >> https://lists.osgeo.org/mailman/listinfo/gdal-dev
> >>
> >>
> >> --
> >> Tom Moore
> >> Spatial Planning Systems
> >> 960 Burkes Bluff Lane
> >> Deep River ON  K0J 1P0
> >> Canada
> >>
> >> Phone: +1 613 584 9354
> >>
> >>
> -------------- next part --------------
> An HTML attachment was scrubbed...
> URL: <
> http://lists.osgeo.org/pipermail/gdal-dev/attachments/20260813/1850b865/attachment.htm
> >
>
> ------------------------------
>
> Subject: Digest Footer
>
> _______________________________________________
> gdal-dev mailing list
> [email protected]
> https://lists.osgeo.org/mailman/listinfo/gdal-dev
>
>
> ------------------------------
>
> End of gdal-dev Digest, Vol 267, Issue 6
> ****************************************
>
_______________________________________________
gdal-dev mailing list
[email protected]
https://lists.osgeo.org/mailman/listinfo/gdal-dev

Reply via email to