adiwg / mdJson-schemas

JSON schemas, examples, and templates for ADIwg metadata standards
http://www.adiwg.org/projects/
GNU Lesser General Public License v3.0
18 stars 15 forks source link

projection new object #157

Closed stansmith907 closed 5 years ago

stansmith907 commented 6 years ago

Schema rules for projection: "a complete parameter set of the projection that was used for the data set."

mdJson:

{
   "spatialReferenceSystem": [
      {
         "referenceSystemType": "MD_ReferenceSystemTypeCode",
         "referenceSystemIdentifier": {},
         "referenceSystemWKT": "",
         "referenceSystemParameterSet": {
            "projection": {
               "projectionIdentifier": {},
               "gridSystem": "", //dropped
               "gridSystemName": "", //dropped
               "gridIdentifier": {},
               "gridZone": "",
               "projection": "", //dropped
               "projectionName": "", //dropped
               "standardParallel1": 9.9,
               "standardParallel2": 9.9,
               "longitudeOfCentralMeridian": 9.9,
               "latitudeOfProjectionOrigin": 9.9,
               "falseEasting": 9.9,
               "falseNorthing": 9.9,
               "falseEastingNorthingUnits": "",
               "scaleFactorAtEquator": 9.9,
               "heightOfProspectivePointAboveSurface": 9.9,
               "longitudeOfProjectionCenter": 9.9,
               "latitudeOfProjectionCenter": 9.9,
               "scaleFactorAtCenterLine": 9.9,
               "scaleFactorAtCentralMeridian": 9.9,
               "straightVerticalLongitudeFromPole": 9.9,
               "scaleFactorAtProjectionOrigin": 9.9,
               "azimuthAngle": 9.9,
               "azimuthMeasurePointLongitude": 9.9,
               "obliqueLinePoint": [],
               "landsatNumber": 9,
               "landsatPath": 9,
               "localPlanarDescription": "", //dropped
               "localPlanarGeoreference": "", //dropped
               "otherGridDescription": "", //dropped
               "otherProjectionDescription": "", //dropped
               "local": {} //added
            },
            "geodetic": {},
            "verticalDatum": {},
            "local": {} //dropped
         }
      }
   ]
}

Rules:

Definitions:

FGDC mapping: It would be tedious to show the mapping from mdJson to fgdc since the FGDC model establishes a unique path for each of the 28 projections while the ADIwg mdJson model abstracts these into a few (3) parameter set objects. However, to get an approximation, all the above elements are mapped into the following FGDC sections - which would require 452 lines to expand - differently for each of the 28 projections.

<metadata>
  <spref>
    <horizsys>
      <planar>
        <mapproj>
          <albers>...</albers>
          ...
          <vdgrin>...</vdgrin>
        </mapproj>
        <gridsys>
          <utm>...</utm>
          ...
        </gridsys>
        <localp>...</localp>
        <planci>...</planci>
      </planar>
    </horizsys>
  </spref>
</metadata>

ISO 19115-2 mapping: The projection elements map to multiple classes in ISO 19115-2 not yet implemented. Most of the projection object elements map to ISO 19115-2 classes MD_ProjectionParameters, MD_ObliqueLineAzimuth, and MD_ObliqueLinePoint. However, these ISO classes were not added to the ISO XSD so I have no means of verifying my example is correct. Further, adding these classes to an ISO record will cause validation against the XSD to fail. Note that not all of the projection parameters map to ISO, some projections found in FGDC are not supported in ISO.

<gmd:referenceSystemInfo>
    <gmd:MD_CRS>
        <gmd:projection>
            <gmd:RS_Identifier>
                <gmd:code>
                    <gco:CharacterString></gco:CharacterString>
                </gmd:code>
            </gmd:RS_Identifier>
        </gmd:projection>
        <gmd:ellipsoid>
            <gmd:RS_Identifier>
                <gmd:code>
                    <gco:CharacterString></gco:CharacterString>
                </gmd:code>
            </gmd:RS_Identifier>
        </gmd:ellipsoid>
        <gmd:datum>
            <gmd:RS_Identifier>
                <gmd:code>
                    <gco:CharacterString></gco:CharacterString>
                </gmd:code>
            </gmd:RS_Identifier>
        </gmd:datum>
        <gmd:projectionParameters>
            <gmd:MD_ProjectionParameters>
                <gmd:zone>
                    <gco:Integer>9</gco:Integer>
                </gmd:zone>
                <gmd:standardParallel>
                    <gco:real>9.9</gco:real>
                </gmd:standardParallel>
                <gmd:standardParallel>
                    <gco:real>19.9</gco:real>
                </gmd:standardParallel>
                <gmd:longitudeOfCentralMeridian>
                    <gco:real>9.9</gco:real>
                </gmd:longitudeOfCentralMeridian>
                <gmd:latitudeOfProjectionOrigin>
                    <gco:real>9.9</gco:real>
                </gmd:latitudeOfProjectionOrigin>
                <gmd:falseEasting>
                    <gco:real>9.9</gco:real>
                </gmd:falseEasting>
                <gmd:falseNorthing>
                    <gco:real>9.9</gco:real>
                </gmd:falseNorthing>
                <gmd:falseEastingNorthingUnits>
                    <gmd:unit>9.9</gmd:unit>
                </gmd:falseEastingNorthingUnits>
                <gmd:scaleFactorAtEquator>
                    <gco:real>9.9</gco:real>
                </gmd:scaleFactorAtEquator>
                <gmd:heightOfProspectivePointAboveSurface>
                    <gco:real>9.9</gco:real>
                </gmd:heightOfProspectivePointAboveSurface>
                <gmd:longitudeOfProjectionCenter>
                    <gco:real>9.9</gco:real>
                </gmd:longitudeOfProjectionCenter>
                <gmd:scaleFactorAtCenterLine>
                    <gco:real>9.9</gco:real>
                </gmd:scaleFactorAtCenterLine>
                <gmd:straightVerticalLongitudeFromPole>
                    <gco:real>9.9</gco:real>
                </gmd:straightVerticalLongitudeFromPole>
                <gmd:scaleFactorAtProjectionOrigin>
                    <gco:real>9.9</gco:real>
                </gmd:scaleFactorAtProjectionOrigin>
                <gmd:obliqueLineAzimuthParameter>
                    <gmd:MD_ObliqueLineAzimuth>
                        <gmd:azimuthAngle>
                            <gco:real>9.9</gco:real>
                        </gmd:azimuthAngle>
                        <gmd:azimuthMeasurePointLongitude>
                            <gco:real>9.9</gco:real>
                        </gmd:azimuthMeasurePointLongitude>
                    </gmd:MD_ObliqueLineAzimuth>
                </gmd:obliqueLineAzimuthParameter>
                <gmd:obliqueLinePointParameter>
                    <gmd:MD_ObliqueLinePoint>
                        <gmd:azimuthLineLatitude>
                            <gco:real>9.9</gco:real>
                        </gmd:azimuthLineLatitude>
                        <gmd:azimuthLineLongitude>
                            <gco:real>9.9</gco:real>
                        </gmd:azimuthLineLongitude>
                    </gmd:MD_ObliqueLinePoint>
                </gmd:obliqueLinePointParameter>
                <gmd:obliqueLinePointParameter>
                    <gmd:MD_ObliqueLinePoint>
                        <gmd:azimuthLineLatitude>
                            <gco:real>9.9</gco:real>
                        </gmd:azimuthLineLatitude>
                        <gmd:azimuthLineLongitude>
                            <gco:real>9.9</gco:real>
                        </gmd:azimuthLineLongitude>
                    </gmd:MD_ObliqueLinePoint>
                </gmd:obliqueLinePointParameter>
            </gmd:MD_ProjectionParameters>
        </gmd:projectionParameters>
    </gmd:MD_CRS>
</gmd:referenceSystemInfo>

ISO 19115-3 mapping: Does not map to ISO 19115-1/3. This information was removed to ISO 19111 ( I do not have documentation at this time ).

stansmith907 commented 5 years ago

You asked off line whether projectionidentifier, projectionName, projection created a situation similar to geodetic and verticalDatum. Yes, somewhat. I think projectionName could be absorbed into projectionIdentifier, but I would like to keep projection as it hold a internal code for the projections. I need this as FGDC uses different XML tags for each of the recognized projections. Thus projection should not be freely edited in mdEditor, lock to selection list "mapProjection".

I also looked at gridSystem and gridSystemName. I'm more uncertain here. Again, gridSystem holds internal values [ utm | ups | spcs | arcsys | other ] to trigger proper FGDC tags. gridSystemName is filled in by me (parallel to projectionName) with text matching the gridSystem e.g. "Universal Transverse Mercator (UTM)", ect.

FGDC example:

      <planar>
        <gridsys>
          <gridsysn>universal transverse mercator UTM grid system</gridsysn>
          <utm>
            <utmzone>9</utmzone>
            <transmer>
              <sfctrmer>9.9</sfctrmer>
              <longcm>-99.0</longcm>
              <latprjo>19.0</latprjo>
              <feast>1000000.0</feast>
              <fnorth>750000.0</fnorth>
            </transmer>
          </utm>
        </gridsys>
        <planci>
          <plandu>meters</plandu>
        </planci>
      </planar>

gridSystem is set to "utm" when the \<utm> tag is found; gridSystemName text is replaced by mdTranslator to my text (unless system is "other"); projection and projectionName are set when the \<transmer> tag is found. Again, don't edit gridSystem in mdEditor unless it is locked to selection list "mapGrid".

For consistency, and possible expansion, gridSystemName might be incorporated into a new gridSystemIdentifier, but gridZone should persist since there is no clear place for it in identifier.

jlblcc commented 5 years ago

Why not just combine projection and projectionName? If the value exists in the mapProjection codelist, then you can generate the parameter output for the writer. Any other value is considered a "custom projection name" and it will be up to the user to supply the parameter values. Same with gridSystem and gridSystemName. That way we can require either a projectionidentifier/gridSystemIdentifier or projection/gridSystem and the translator can take care of the logic. Otherwise, we're depending on the end user to have specific knowledge of other metadata standards, which is something we should avoid.

I assume otherGridDescription and otherProjectionDescription are only present to support CSDGM since already have properties available to define the parameters?

Also, forgive my ignorance, but you can only define a projection or gridSystem, but not both in the same object, right?

stansmith907 commented 5 years ago

I'm suggesting almost the same thing. Combine projectionName into projectionIdentifier and gridSystemName into gridSystemIdentifier; but leave projection and gridSystem to carry the internal code (codeList value) for the projection and/or grid system.

If the projection or gridSystem code is "other" then require the user to provide an identifier. I'm not sure we should require them to also supply parameters since there are hundreds of defined projections and grid systems not specifically tagged by FGDC; therefore an identifier should be sufficient even without parameters for these. "other" is also an FGDC tag.

Picking a code from within mdEditor will just allow us to populate a few elements of the identifier object either in mdEditor or mdTranslator (mdJSON reader).

Yes, I assume one would only define either a projection or a grid. I believe all grids are based on a projection supplied with parameters to produce a localized rectangular, or possibly circular, grid. So we could define a UTM grid and zone by choosing the Transverse Mercator projection and supplying all the parameters or by specifying the UTM zone 4 grid system. I think. It's been a while since I was a surveyor.

stansmith907 commented 5 years ago

Oops, didn't meant to close issue.

jlblcc commented 5 years ago

We can do it that way, but I think it'll have to be implemented differently in the editor. Doesn't make sense to ask folks to choose "other" to enter an espg code. I think that's confusing. It can be done behind the scenes, I guess. Why not just default to using the parameters if the name is not in the codelist?

Or drop both in favor of identifier with namespace(which makes it explicit - epsg, adiwg, ESRI, etc.)? We can add something like org.adiwg.code.mapGridSystem and org.adiwg.code.mapProjection to the namespace codelist. That makes it clear when you are looking at the mdJSON where those values come from. If we need a name(optional), it can go in the identifier.description. :+1:

So, is this correct as of now:

Also, there is no "other" value in the codelists. If we want to enforce via the schema, the "other" value will need to be defined. Or should this be left up to the translator?

jlblcc commented 5 years ago

Updated main comment. Depends on adiwg/mdCodes#26 and adiwg/mdCodes#27.

stansmith907 commented 5 years ago

I moved local back into projection. It doesn't require a projectionIdentifier by FGDC standards but it handles better internally if all projections have an identifier. That way it has a name and an identifier for the projection, otherwise none. I moved the local object in, not the original separate parameters. I think that helps the original objection some.

stansmith907 commented 5 years ago

I implemented projectionIdentifier as a required element. This means we will always have a projection type (identifier) from the map_projection codelist or a user provided identifier. The codelist includes "parameters" for when there is not an official name for the projection. If the use wants to provide a name for their custom projection projectionIdentifier.name is available.

stansmith907 commented 5 years ago

I did not make projectionIdentifier.name required.

jlblcc commented 5 years ago

I will move local back. Technically this is a breaking change from 2.5.1, but we'll treat it as a bug fix, 2.5.1. :wink:

BTW, with local there this would seem to make more sense:

"projection": {
  "local":{},
  "projection":{},
  "grid":{}
}

Params would go inside of projection object.

stansmith907 commented 5 years ago

Local is a projection, so fits inside projection{} for me. Also, grids always have an associated projection, the parameters don't belong to grid. e.g. UTM is transverse mercator projection; State Plane can be lambert, oblique mercator, transverse mercator, etc.

jlblcc commented 5 years ago

I updated my last comment. :grimacing: , but I'm implementing as is.