<?xml version="1.0" encoding="UTF-8"?>
<!--
  MMP Schema Definition

  Blue Blink One
  https://blueblinkone.com

  This schema is public and free to use.

  Revision 2 (Measure Map Online, 2026): additions only, all optional, so every
  file valid under revision 1 is valid here.
   - POLYGON, POINT, SPOT, GROUP: optional `id` attribute.
   - POLYGON: FILLOPACITY, LINEWIDTHPX, LINESTYLENAME (exact values beside the
     rounded AREATRANSPARENCY / LINEWIDTH / LINESTYLE), SHOWPINSWHENUNLOCKED,
     SHOWPRICELABEL, ISBUFFER, PARENTID, PRODUCTID, TEXTUREROTATION,
     ALTITUDEMODE3D, ALTITUDE3D, EXTRUDED3D, PARCELPROVIDERID, PARCELREFERENCE,
     PARCELEXTRAINFO, TITLELABELMANUAL (1 = the label was placed by hand),
     HEIGHTOFFSET3D (metres the shape is moved up or down in 3D),
     GRIDLINECOLOR, GRIDLINEWIDTHPX, GRIDSHOWCENTRES (the grid's own line
     colour and thickness in pixels; 0 = no dot at each cell's centre),
     BUFFERSOURCEID, BUFFERSETID, BUFFERPART, BUFFERDISTANCE, BUFFERCORNER,
     BUFFERINSIDE, BUFFEREND, BUFFERSIDE, BUFFERMITRELIMIT, BUFFERRING (how a
     buffer was drawn: the shape it follows and the set its pieces share, by
     their ids in the file, which piece it is, the distance in metres, its
     corners, inside the shape or round it, a line's ends and side, the mitre
     limit, and 1 = a ring left inside one of its pieces).
   - POINT: ALT3D. SPOT: ALT3D, PRODUCTID, PRODUCTIDS. GROUP: SHOWBOUNDS.
   - POLYGON, SPOT: PRODUCTIDS, every product on the shape when it has more
     than one, space-separated; PRODUCTID is still the first.
   - Root: LAYER (reference and MBTiles layers) and PROJECT (settings) after
     GROUPS; optional projectId / projectName attributes.
   - LINESTYLE 0-5 (5 = dash-dot), AREATRANSPARENCY 0-10 (0 = opaque): values
     already written in practice.
-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <!-- ================================================== -->
  <!-- Simple Types & Restrictions                        -->
  <!-- ================================================== -->

  <xs:simpleType name="BinaryFlag">
    <xs:restriction base="xs:integer">
      <xs:enumeration value="0"/>
      <xs:enumeration value="1"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="HexColorType">
    <xs:restriction base="xs:string">
      <xs:pattern value="(#[a-fA-F0-9]{6}|[a-fA-F0-9]{6})"/> <!-- Hexadecimal color (with or without #) -->
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="LineWidthType">
    <xs:restriction base="xs:integer">
      <xs:minInclusive value="0"/>
      <xs:maxInclusive value="10"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="AreaTransparencyType">
    <xs:restriction base="xs:integer">
      <xs:minInclusive value="0"/> <!-- 0 = fully opaque fill -->
      <xs:maxInclusive value="10"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="OpacityType">
    <xs:restriction base="xs:float">
      <xs:minInclusive value="0.0"/>
      <xs:maxInclusive value="1.0"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="LineStyleNameType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="solid"/>
      <xs:enumeration value="dashed"/>
      <xs:enumeration value="dotted"/>
      <xs:enumeration value="dashed_filled"/>
      <xs:enumeration value="dotted_filled"/>
      <xs:enumeration value="dash_dot"/>
      <xs:enumeration value="dash_dot_dot"/>
      <xs:enumeration value="dash_dash_dot"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="BufferCornerType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="sharp"/>
      <xs:enumeration value="round"/>
      <xs:enumeration value="cut"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="BufferEndType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="round"/>
      <xs:enumeration value="flat"/>
      <xs:enumeration value="square"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="BufferSideType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="both"/>
      <xs:enumeration value="left"/>
      <xs:enumeration value="right"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="LayerKindType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="image_overlay"/>
      <xs:enumeration value="mbtiles"/>
      <xs:enumeration value="vector"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="LatitudeType">
    <xs:restriction base="xs:float">
      <xs:minInclusive value="-90.0"/>
      <xs:maxInclusive value="90.0"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="LongitudeType">
    <xs:restriction base="xs:float">
      <xs:minInclusive value="-180.0"/>
      <xs:maxInclusive value="180.0"/>
    </xs:restriction>
  </xs:simpleType>

  <!-- ================================================== -->
  <!-- Complex Types                                      -->
  <!-- ================================================== -->

  <!-- PICTURE Structure -->
  <xs:complexType name="PictureType">
    <!-- xs:all allows fields in any order -->
    <xs:all>
      <xs:element name="DATE" type="xs:string" minOccurs="0"/> <!-- ISO 8601 -->
      <xs:element name="PICTUREURL" type="xs:string"/>
      <xs:element name="PICTURETHUMBNAILURL" type="xs:string" minOccurs="0"/>
      <xs:element name="SHOWPICTINREPORT" type="BinaryFlag" minOccurs="0"/>
    </xs:all>
  </xs:complexType>

  <xs:complexType name="PicturesContainerType">
    <!-- Lists must use xs:sequence -->
    <xs:sequence>
      <xs:element name="PICTURE" type="PictureType" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>

  <!-- GRID Structure -->
  <xs:complexType name="GridType">
    <xs:all>
      <xs:element name="CELLWIDTH" type="xs:float"/>
      <xs:element name="CELLHEIGHT" type="xs:float"/>
      <xs:element name="BEARING" type="xs:float"/>
      <xs:element name="REFLATITUDE" type="LatitudeType"/>
      <xs:element name="REFLONGITUDE" type="LongitudeType"/>
      <xs:element name="SHOWGRID" type="BinaryFlag"/>
    </xs:all>
  </xs:complexType>

  <!-- POINT Structure -->
  <xs:complexType name="PointDescType">
    <xs:all>
      <xs:element name="SHOWDESC" type="BinaryFlag" minOccurs="0"/>
      <xs:element name="SHOWLABELBACKGROUND" type="BinaryFlag" minOccurs="0"/>
      <xs:element name="SHOWDESCINREPORT" type="BinaryFlag" minOccurs="0"/>
      <xs:element name="DESC" type="xs:string" minOccurs="0"/>
      <xs:element name="DESCLAT" type="LatitudeType"  minOccurs="0"/>
      <xs:element name="DESCLONG" type="LongitudeType" minOccurs="0"/>
    </xs:all>
  </xs:complexType>

  <xs:complexType name="PointType">
    <xs:all>
      <xs:element name="LAT" type="LatitudeType"/>
      <xs:element name="LONG" type="LongitudeType"/>
      <xs:element name="ALT" type="xs:float" minOccurs="0"/>
      <xs:element name="DESCPOINT" type="PointDescType" minOccurs="0"/>
      <xs:element name="PICTURES" type="PicturesContainerType" minOccurs="0"/>
      <xs:element name="ALT3D" type="xs:float" minOccurs="0"/>
    </xs:all>
    <xs:attribute name="id" type="xs:string" use="optional"/>
  </xs:complexType>

  <!-- GROUP Structure -->
  <xs:complexType name="GroupType">
    <xs:all>
      <xs:element name="ID" type="xs:string"/>
      <xs:element name="NAME" type="xs:string"/>
      <xs:element name="DESCRIPTION" type="xs:string" minOccurs="0"/>
      <xs:element name="GROUPCOLOR">
        <xs:simpleType>
          <xs:restriction base="xs:integer">
            <xs:minInclusive value="0"/>
            <xs:maxInclusive value="7"/>
          </xs:restriction>
        </xs:simpleType>
      </xs:element>
      <xs:element name="GROUPCUSTOMCOLOR" type="HexColorType" minOccurs="0"/>
      <xs:element name="SHOWBOUNDS" type="BinaryFlag" minOccurs="0"/>
    </xs:all>
    <xs:attribute name="id" type="xs:string" use="optional"/>
  </xs:complexType>

  <!-- POLYGON Structure -->
  <xs:complexType name="PolygonType">
    <!-- Properties in any order -->
    <xs:all>
      <xs:element name="GROUPID" type="xs:string" minOccurs="0"/>
      <xs:element name="NAME" type="xs:string"/>
      <xs:element name="DESCRIPTION" type="xs:string" minOccurs="0"/>
      <xs:element name="ISHOLE" type="BinaryFlag"/>
      <xs:element name="BLOCKED" type="BinaryFlag"/>
      <xs:element name="SHAPE" default="0">
        <xs:simpleType>
          <xs:restriction base="xs:integer">
            <xs:enumeration value="0"/>  <!-- 0: No shape. It's an ordinary polygon. (Default)-->
            <xs:enumeration value="1"/> <!-- 1: circle -->
            <xs:enumeration value="2"/> <!-- 2: rectangle -->
          </xs:restriction>
        </xs:simpleType>
      </xs:element>
      <xs:element name="NOSURFACE" type="BinaryFlag"/>
      <xs:element name="SHOWPINS" type="BinaryFlag"/>
      <xs:element name="SHOWDISTANCES" type="BinaryFlag"/>
      <xs:element name="LINECOLOR">
        <xs:simpleType>
          <xs:restriction base="xs:integer">
            <xs:minInclusive value="0"/>
            <xs:maxInclusive value="6"/>
          </xs:restriction>
        </xs:simpleType>
      </xs:element>
      <xs:element name="LINECUSTOMCOLOR" type="HexColorType" minOccurs="0"/>
      <xs:element name="LINEWIDTH" type="LineWidthType"/>
      <xs:element name="LINESTYLE">
        <xs:simpleType>
          <xs:restriction base="xs:integer">
            <xs:minInclusive value="0"/>
            <xs:maxInclusive value="5"/> <!-- 5 = dash-dot -->
          </xs:restriction>
        </xs:simpleType>
      </xs:element>
      <xs:element name="AREACOLOR">
        <xs:simpleType>
          <xs:restriction base="xs:integer">
            <xs:minInclusive value="0"/>
            <xs:maxInclusive value="6"/>
          </xs:restriction>
        </xs:simpleType>
      </xs:element>
      <xs:element name="AREACUSTOMCOLOR" type="HexColorType" minOccurs="0"/>
      <xs:element name="AREATRANSPARENCY" type="AreaTransparencyType"/>
      <xs:element name="SHOWNAME" type="BinaryFlag"/>
      <xs:element name="SHOWLABELBACKGROUND" type="BinaryFlag"/>
      <xs:element name="SHOWAREAMEASURE" type="BinaryFlag"/>
      <xs:element name="SHOWPERIMETERMEASURE" type="BinaryFlag"/>

      <xs:element name="COORDINATEPOLYGONLABELLATITUDE" type="LatitudeType"/>
      <xs:element name="COORDINATEPOLYGONLABELLONGITUDE" type="LongitudeType"/>
      <xs:element name="COORDINATEPERIMETERLABELLATITUDE" type="LatitudeType"/>
      <xs:element name="COORDINATEPERIMETERLABELLONGITUDE" type="LongitudeType"/>
      <xs:element name="COORDINATEAREALABELLATITUDE" type="LatitudeType"/>
      <xs:element name="COORDINATEAREALABELLONGITUDE" type="LongitudeType"/>

      <xs:element name="GRID" type="GridType" minOccurs="0"/>
      <xs:element name="PICTURES" type="PicturesContainerType" minOccurs="0"/>

      <!-- Revision 2 -->
      <xs:element name="FILLOPACITY" type="OpacityType" minOccurs="0"/>
      <xs:element name="LINEWIDTHPX" type="xs:float" minOccurs="0"/>
      <xs:element name="LINESTYLENAME" type="LineStyleNameType" minOccurs="0"/>
      <xs:element name="SHOWPINSWHENUNLOCKED" type="BinaryFlag" minOccurs="0"/>
      <xs:element name="SHOWPRICELABEL" type="BinaryFlag" minOccurs="0"/>
      <xs:element name="ISBUFFER" type="BinaryFlag" minOccurs="0"/>
      <xs:element name="PARENTID" type="xs:string" minOccurs="0"/>
      <xs:element name="BUFFERSOURCEID" type="xs:string" minOccurs="0"/>
      <xs:element name="BUFFERSETID" type="xs:string" minOccurs="0"/>
      <xs:element name="BUFFERPART" type="xs:nonNegativeInteger" minOccurs="0"/>
      <xs:element name="BUFFERDISTANCE" type="xs:float" minOccurs="0"/>
      <xs:element name="BUFFERCORNER" type="BufferCornerType" minOccurs="0"/>
      <xs:element name="BUFFERINSIDE" type="BinaryFlag" minOccurs="0"/>
      <xs:element name="BUFFEREND" type="BufferEndType" minOccurs="0"/>
      <xs:element name="BUFFERSIDE" type="BufferSideType" minOccurs="0"/>
      <xs:element name="BUFFERMITRELIMIT" type="xs:float" minOccurs="0"/>
      <xs:element name="BUFFERRING" type="BinaryFlag" minOccurs="0"/>
      <xs:element name="PRODUCTID" type="xs:string" minOccurs="0"/>
      <xs:element name="TEXTUREROTATION" type="xs:float" minOccurs="0"/>
      <xs:element name="ALTITUDEMODE3D" type="xs:string" minOccurs="0"/>
      <xs:element name="ALTITUDE3D" type="xs:float" minOccurs="0"/>
      <xs:element name="EXTRUDED3D" type="BinaryFlag" minOccurs="0"/>
      <xs:element name="TITLELABELMANUAL" type="BinaryFlag" minOccurs="0"/>
      <xs:element name="HEIGHTOFFSET3D" type="xs:float" minOccurs="0"/>
      <xs:element name="GRIDLINECOLOR" type="HexColorType" minOccurs="0"/>
      <xs:element name="GRIDLINEWIDTHPX" type="xs:float" minOccurs="0"/>
      <xs:element name="GRIDSHOWCENTRES" type="BinaryFlag" minOccurs="0"/>
      <xs:element name="PRODUCTIDS" type="IdListType" minOccurs="0"/>
      <xs:element name="PARCELPROVIDERID" type="xs:string" minOccurs="0"/>
      <xs:element name="PARCELREFERENCE" type="xs:string" minOccurs="0"/>
      <xs:element name="PARCELEXTRAINFO" type="xs:string" minOccurs="0"/>

      <!-- Container for the list of points -->
      <xs:element name="POINTS" minOccurs="0">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="POINT" type="PointType" minOccurs="0" maxOccurs="unbounded"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:all>
    <xs:attribute name="id" type="xs:string" use="optional"/>
  </xs:complexType>

  <!-- SPOT Structure -->
  <xs:complexType name="SpotDescType">
    <xs:all>
      <xs:element name="SHOWDESC" type="BinaryFlag" minOccurs="0"/>
      <xs:element name="SHOWDESCINREPORT" type="BinaryFlag" minOccurs="0"/>
      <xs:element name="DESC" type="xs:string" minOccurs="0"/>
    </xs:all>
  </xs:complexType>

  <xs:complexType name="SpotType">
    <xs:all>
      <xs:element name="GROUPID" type="xs:string" minOccurs="0"/>
      <xs:element name="NAME" type="xs:string"/>
      <xs:element name="SHOWNAME" type="BinaryFlag"/>
      <xs:element name="SHOWLABELBACKGROUND" type="BinaryFlag"/>
      <xs:element name="ICON" type="xs:integer"/>
      <xs:element name="SPOTICONCOLOR">
        <xs:simpleType>
          <xs:restriction base="xs:integer">
            <xs:minInclusive value="0"/>
            <xs:maxInclusive value="7"/>
          </xs:restriction>
        </xs:simpleType>
      </xs:element>
      <xs:element name="SPOTICONCUSTOMCOLOR" type="HexColorType" minOccurs="0"/>
      <xs:element name="LAT" type="LatitudeType"/>
      <xs:element name="LONG" type="LongitudeType"/>
      <xs:element name="ALT" type="xs:float" minOccurs="0"/>
      <xs:element name="PICTURES" type="PicturesContainerType" minOccurs="0"/>
      <xs:element name="COORDINATESPOTNAMELATITUDE" type="LatitudeType"/>
      <xs:element name="COORDINATESPOTNAMELONGITUDE" type="LongitudeType"/>
      <xs:element name="DESCSPOT" type="SpotDescType" minOccurs="0"/>
      <xs:element name="ALT3D" type="xs:float" minOccurs="0"/>
      <xs:element name="PRODUCTID" type="xs:string" minOccurs="0"/>
      <xs:element name="PRODUCTIDS" type="IdListType" minOccurs="0"/>
    </xs:all>
    <xs:attribute name="id" type="xs:string" use="optional"/>
  </xs:complexType>

  <!-- Ids, space-separated (PRODUCTIDS) -->
  <xs:simpleType name="IdListType">
    <xs:list itemType="xs:token"/>
  </xs:simpleType>

  <!-- IMAGELAYER Structure -->
  <xs:complexType name="ImageLayerType">
    <xs:all>
      <xs:element name="NAME" type="xs:string"/>
      <xs:element name="IMAGEURL" type="xs:string" minOccurs="0"/>
      <xs:element name="OPACITY" type="OpacityType"/>
      <xs:element name="LAT1" type="LatitudeType"/>
      <xs:element name="LONG1" type="LongitudeType"/>
      <xs:element name="LAT2" type="LatitudeType"/>
      <xs:element name="LONG2" type="LongitudeType"/>
    </xs:all>
  </xs:complexType>

  <!-- LAYER Structure (revision 2): layers an IMAGELAYER cannot describe -->
  <xs:complexType name="LayerType">
    <xs:all>
      <xs:element name="NAME" type="xs:string"/>
      <xs:element name="URL" type="xs:string"/>
      <xs:element name="OPACITY" type="OpacityType" minOccurs="0"/>
      <xs:element name="LAT1" type="LatitudeType" minOccurs="0"/>
      <xs:element name="LONG1" type="LongitudeType" minOccurs="0"/>
      <xs:element name="LAT2" type="LatitudeType" minOccurs="0"/>
      <xs:element name="LONG2" type="LongitudeType" minOccurs="0"/>
      <xs:element name="FEATURECOUNT" type="xs:integer" minOccurs="0"/>
    </xs:all>
    <xs:attribute name="type" type="LayerKindType" use="required"/>
  </xs:complexType>

  <!-- PROJECT Structure (revision 2): settings that travel with the file -->
  <xs:complexType name="ProjectSettingsType">
    <xs:all>
      <xs:element name="TAXRATE" type="xs:float" minOccurs="0"/>
      <xs:element name="CLIENTNAME" type="xs:string" minOccurs="0"/>
      <xs:element name="DEFAULTPRODUCTID" type="xs:string" minOccurs="0"/>
    </xs:all>
  </xs:complexType>

  <!-- ================================================== -->
  <!-- Main Definition                                    -->
  <!-- ================================================== -->

  <xs:element name="POLYGONS">
    <xs:complexType>
      <!-- Root uses xs:sequence to maintain the order of lists -->
      <xs:sequence>

        <xs:element name="POLYGON" type="PolygonType" minOccurs="0" maxOccurs="unbounded"/>

        <xs:element name="SPOT" type="SpotType" minOccurs="0" maxOccurs="unbounded"/>

        <xs:element name="IMAGELAYER" type="ImageLayerType" minOccurs="0" maxOccurs="unbounded"/>

        <xs:element name="GROUPS" minOccurs="0">
           <xs:complexType>
            <xs:sequence>
              <xs:element name="GROUP" type="GroupType" minOccurs="0" maxOccurs="unbounded"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>

        <xs:element name="LAYER" type="LayerType" minOccurs="0" maxOccurs="unbounded"/>

        <xs:element name="PROJECT" type="ProjectSettingsType" minOccurs="0"/>

      </xs:sequence>

      <!-- Optional Root Attributes -->
      <xs:attribute name="id" type="xs:string" use="optional"/>
      <xs:attribute name="creator" type="xs:string" use="optional"/>
      <xs:attribute name="date" type="xs:string" use="optional"/>
      <xs:attribute name="project" type="xs:string" use="optional"/>
      <xs:attribute name="projectId" type="xs:string" use="optional"/>
      <xs:attribute name="projectName" type="xs:string" use="optional"/>

    </xs:complexType>
  </xs:element>

</xs:schema>