Skip to content

Maxar-Corp/maxar-geospatial-platform-java

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 

Repository files navigation

Maxar Geospatial Platform SDK

Maven Central javadoc

Table of Contents

Overview


The Java MPS package uses a builder pattern to build and send specific API calls. The SDK supports the following Open Geospatial Consortium standard protocols: WFS, WMS, WMTS.

View the Javadoc Here

Installation Instructions


Maven (recommended)

<dependency>
  <groupId>io.github.maxar-corp</groupId>
  <artifactId>maxar-portal-java</artifactId>
  <version>{maxar-portal-java.version}</version>
</dependency>

Gradle

implementation group: 'io.github.maxar-corp', name: 'maxar-portal-java', version: '2.0.0'

Ivy

<dependency org="io.github.maxar-corp" name="maxar-portal-java" rev="2.0.0"/>

Grape

@Grapes(
      @Grab(group='io.github.maxar-corp', module='maxar-portal-java', version='2.0.0')
  )

How To Import

import io.github.maxar.corp.MaxarPortal;

Authentication


Access to Maxar API resources requires valid credentials. The package looks for a credentials file located in the users home directory. Users should have a file here titled .MGP-config and should resemble the following exactly:

[mgp]
user_name=<[email protected]>
user_pasword=<mySuperSecretPassword>
client_id=<my-client-id>

Replace these values with the credentials provided to you by Maxar.

Optionally, credentials can also be supplied by passing them in as builder arguments when the call is instantiated using .username() .password() and .clientID()

Workflow


Example

The following is an example workflow to make a simple wfs call with a bounding box and a few filters using the .searchToString() function

import io.github.maxar.MGPSDK.Streaming;

public class Main {

  public static void main(String[] args) {
    Streaming wfsCall = Streaming.builder()
            .bbox("39.84387,-105.05608,39.95133,-104.94827")
            .bbox("EPSG:4326")
            .filter("acquisitionDate>='2022-01-01'")
            .filter("cloudCover<0.20")
            .build();

    System.out.println(wfsCall.searchToString());
  }

}

The search function performs a WFS request that returns a string containing a GeoJSON formatted list of features that match the parameters sent in the call.

Example response received from the server for the above call

{
   "type":"FeatureCollection",
   "features":[
      {
         "type":"Feature",
         "id":"7dea6ffc-e4b3-a507-f7e7-af315d32da29",
         "geometry":{
            "type":"Polygon",
            "coordinates":[...]           ]
         },
         "geometry_name":"featureGeometry",
         "properties":{
            "featureId":"7dea6ffc-e4b3-a507-f7e7-af315d32da29",
            "cloudCover":0,
            "sunAzimuth":159.64929,
            "sunElevation":24.48628,
            "offNadirAngle":26.880003,
            "groundSampleDistance":0.38,
            etc...
         }
      },
      {...}
   ],
   "totalFeatures":"unknown",
   "numberReturned":4,
   "timeStamp":"2023-01-18T16:51:58.818Z",
   "crs":{
      "type":"name",
      "properties":{
         "name":"urn:ogc:def:crs:EPSG::4326"
      }
   }
}

Making a call

Because the sdk utilizes a builder pattern, the parameters you want to add to the call can be chained on the child class (Streaming, Basemap, Analytics) instantiation. Once the Portal is built, it contains methods that correspond to the different available functionality for making and returning OGC calls.

Records for WFS Results

A FeatureCollection is built and provided for each child to view and efficiently parse results from WFS results returned from the .search() method. StreamingFeatureCollection, BasemapFeatureCollection, AnalyticsFeatureCollection

Below are a few examples of accessing metadata from returned calls:

public class Main {

  public static void main(String[] args) {
    Streaming wfsCall = Streaming.builder()
            .bbox("39.84387,-105.05608,39.95133,-104.94827")
            .filter("acquisitionDate>='2022-01-01'")
            .filter("cloudCover<0.20")
            .build();

    StreamingFeatureCollection results = wfsCall.search();

    //Get number of images returned
    int numberReturned = results.numberReturned();

    //return the feature ID of every feature returned
    for (StreamingFeatures feature : results.features()) {
      System.out.println(feature.getId());
    }

    //print the coordinates of the centroid of the first returned feature
    Centroid firstCentroid = results.features()[0].properties.centroid();
    System.out.println(Arrays.toString(firstCentroid.coordinates()));
  }

}

Furthermore, the geometry returned within the FeatureCollection is an instance of the JTS Geometry class providing all the methods returned from that class. Locationtech JTS Geometry

import io.github.maxar.MGPSDK.StreamingFeatureCollection;
import java.util.Arrays;
import org.locationtech.jts.geom.Envelope;
import org.locationtech.jts.geom.Geometry;

public class Main {

  public static void main(String[] args) {
    Streaming wfsCall = Streaming.builder()
            .bbox("39.84387,-105.05608,39.95133,-104.94827")
            .filter("acquisitionDate>='2022-01-01'")
            .filter("cloudCover<0.20")
            .build();

    StreamingFeatureCollection results = wfsCall.search();

    //Collect the first feature's geometry
    Geometry firstFeatureGeometry = results.features()[0].geometry;

    //Get the geometry type
    System.out.println("Geometry Type: " + firstFeatureGeometry.getGeometryType());

    //Get the coordinates
    System.out.println("Geometry Coordinates: " +
            Arrays.toString(firstFeatureGeometry.getCoordinates()));

    //Create an envelope
    Envelope envelope = firstFeatureGeometry.getEnvelope();

    //Get the area
    Double area = firstFeatureGeometry.getArea();
  }

}

If for any reason you require the raw string return from a WFS call, utilize the Ogc.searchToString() method.

public class Main {

  public static void main(String[] args) {
    Streaming wfsCall = Streaming.builder()
            .bbox("39.84387,-105.05608,39.95133,-104.94827")
            .filter("acquisitionDate>='2022-01-01'")
            .filter("cloudCover<0.20")
            .build();

    String results = wfsCall.searchToString();
    System.out.println(results);
  }
}

Search

Ogc.search()
Performs a WFS search.
Return WFS results as a FeatureCollection
Builder parameters:
.bbox()
.filter()
.rawFilter()
.srsname()
.featureId()
.requestType()
.typeName()

Example Call

import io.github.maxar.MGPSDK.Streaming;
import io.github.maxar.MGPSDK.StreamingFeatureCollection;

public class Main {

  public static void main(String[] args) {

    //Build the call
    Streaming wfsCall = Streaming.builder()
            .bbox("4828455.4171,-11686562.3554,4830614.7631,-11684030.3789")
            .filter("(acquisitionDate>='2022-01-01')AND(cloudCover<0.20)")
            .srsname("ESPG:3857")
            .build();

    //Make the call
    StreamingFeatureCollection wfsResults = wfsCall.search();

  }

}

Download CSV

Ogc.downloadCsv()
Performs a WFS request in the same manner as .search(), downloading a CSV of the results. CSV will be downloaded to the defined path, or defaulted to the user's downloads directory. Filename can be set with .filename() .bbox()
.filter()
.rawFilter()
.srsname()
.downloadPath()
.fileName()
.typeName()

Example call:

import io.github.maxar.MGPSDK.Streaming;

public class Main {

  public static void main(String[] args) {

    //Build the call
    Streaming csvCall = Streaming.builder()
            .bbox("4828455.4171,-11686562.3554,4830614.7631,-11684030.3789")
            .rawFilter("(acquisitionDate>='2022-01-01')AND(cloudCover<0.20)")
            .srsname("EPSG:3857")
            .fileName("test")
            .downloadPath("C:/Users/user/Desktop/Images")
            .build();

    //Make the call
    csvCall.downloadCsv();

  }

}

Download Shapefile

Ogc.downloadShapeFile()
Performs a WFS request in the same manner as .search(), downloading a Shapefile of the results. Shapefile will be downloaded to the defined path, or defaulted to the user's downloads directory. Filename can be set with .filename() .bbox()
.filter()
.rawFilter()
.srsname()
.downloadPath()
.fileName()
.typeName()

Example call:

import io.github.maxar.MGPSDK.Streaming;

public class Main {

  public static void main(String[] args) {

    //Build the call
    Streaming shapefile = Streaming.builder()
            .bbox("4828455.4171,-11686562.3554,4830614.7631,-11684030.3789")
            .rawFilter("(acquisitionDate>='2022-01-01')AND(cloudCover<0.20)")
            .srsname("EPSG:3857")
            .fileName("test")
            .downloadPath("C:/Users/user/Desktop/Images")
            .build();

    //Make the call
    shapefile.downloadShapeFile();

  }

}

Download Image

Ogc.downloadImage()
Get the requested image using WMS. If .download() is provided, image will be downloaded to the defined path, or defaulted to the user's downloads directory. If not, the function returns the blob from the API which can then be converted to an instance of a java.io.InputStream
Returns location the image was downloaded to
Builder parameters:
.bbox()
.filter()
.rawFilter()
.srsname()
.height()
.width()
.imageFormat()
.downloadPath()
.fileName()
.download()
.legacyId()
.typeName()

Example Call

public class Main {

    public static void main(String[] args) {
        
        //Build the call
        Streaming wmsCall = Streaming.builder()
            .bbox("4828455.4171,-11686562.3554,4830614.7631,-11684030.3789")
            .filter("(acquisitionDate>='2022-01-01')AND(cloudCover<0.20)")
            .srsname("ESPG:3857")
            .height(1000)
            .width(1000)
            .imageFormat("png")
            .fileName("test")
            .downloadPath("C:/Users/user/Desktop/Images")
            .build();

        //Make the call
        String downloadLocation = wmsCall.downloadImage();

        //View the response
        System.out.println(downloadLocation);
    }

}

Get Tile List

Ogc.getTileList()
Returns a Hashmap<String, String> of WMTS calls that can be used to return all of the tiles in a given AOI. The key is a String list containing a tiles row, column, and zoom level. The value is the associated api call. If you want to download all tiles and do not care about the individual calls, use the .downloadTiles() method instead
Builder Parameters:
.bbox()
.srsname()
.zoomLevel()

Example Call

public class Main {

    public static void main(String[] args) {
        
        //Build the call
        Streaming wmtsCall = Streaming.builder()
                .bbox("4828455.4171,-11686562.3554,4830614.7631,-11684030.3789")
                .srsname("EPSG:4326")
                .zoomLevel(12)
                .build();

        //Make the call
        Hashmap<String, String> wmtsApiCallList = wmtsCall.getTileList();

        //View the response
        wmtsApiCallList.entrySet().forEach(entry -> 
            System.out.println(entry.getKey() + " " + entry.getValue())
        );
    }
}

Download Tiles

streaming.downloadTiles()
Downloads all the tiles in a given bounding box at a given zoom level. Returns a message indicating success or failures and the location of the downloaded tiles. A base file name can be added with the .fileName() method. This file name will be appended with a tile's row column and zoom level
Builder Parameters:
.bbox()
.srsname()
.zoomLevel()
.imageFormat()
.fileName()
.downloadPath()
.typeName()

Example Call

public class Main {

    public static void main(String[] args) {
        
        //Build the call
        Streaming wmtsCall = Streaming.builder()
            .bbox("4828455.4171,-11686562.3554,4830614.7631,-11684030.3789")
            .zoomLevel(12)
            .imageFormat("geotiff")
            .downloadPath("C:\\Users\\user\\Desktop\\Seattle")
            .fileName("seattle_tile")
            .build();

        //Make the call
        String results = wmtsCall.downloadTiles();

        //View the response
        System.out.println(results);
    }
}

Get Full Resolution Image

Streaming.getFullResImage()
This method downloads the full scale resolution of a desired AOI. Utilizes multithreading to try to speed up the download process. Full resolution images are broken into tiles and downloaded as separate full resolution images. The number of threads must be set by the user. 50 is a good starting point. The more threads in use the quicker the download process however the more unstable. If you are getting a number of failed returns, terminate the process, lower the number of threads and try again. Only available on the Streaming class
Builder Parameters:
.featureId()
.threadNumber()
.bbox()
.srsname()
.imageFormat()
.downloadPath()
.fileName()

Example Call

public class Main {

    public static void main(String[] args) {
        
        //Build the call
        Streaming fullResDownload = Streaming.builder()
            .featureId("7dea6ffce4b3a507f7e7af315d32da29")
            .imageFormat("geotiff")
            .filename("test")
            .downloadPath("C:/Users/user/Desktop/FullRes")
            .build();

        //Make the call
        fullResDownload.getFullResImage();

    }

}

Streaming, Basemap, Analytics

Streaming, Basemap, and Analytics all inherit from the Ogc class and therefore share all properties and methods. If an Ogc method is not specifically supported by the child, an UnsupportedOperationException will be thrown. All calls listed in the workflow theoretically can be used by all children. For example:

Analytics WFS search:

import io.github.maxar.MGPSDK.Analytics;
import io.github.maxar.MGPSDK.AnalyticsFeatureCollection;

public class Main {

  public static void main(String[] args) {
    Analytics wfsCall = Analytics.builder()
            .bbox("40.407222,-74.363708,41.271614,-73.449097")
            .bbox("EPSG:4326")
            .filter("sensor='Landsat'")
            .typeName("Maxar:layer_pcm_eo_2020")
            .build();

    AnalyticsFeatureCollection pcmFeatures = wfsCall.search();
  }

}

Basemap WMS download Image:

public class Main {

    public static void main(String[] args) {
        
        //Build the call
        Basemap wmsCall = Basemap.builder()
            .bbox("4828455.4171,-11686562.3554,4830614.7631,-11684030.3789")
            .filter("product_name='VIVID_STANDARD_30'")
            .srsname("ESPG:3857")
            .height(1000)
            .width(1000)
            .imageFormat("png")
            .filename("test")
            .downloadPath("C:/Users/user/Desktop/Images")
            .build();

        //Make the call
        String downloadLocation = wmsCall.downloadImage();

        //View the response
        System.out.println(downloadLocation);
    }

}

Username

.username(String)
Used if not using a .MPS-config file.

Password

.password(String)
Used if not using a .MPS-config file.

ClientId

.clientId(String)
Used if not using a .MPS-config file.

Bounding box

.bbox(String)
Accepts a string containing the bbox in yx order. All calls default to an EPSG:4326 projection. To use a different one utilize the .srsname() method. Example EPSG:4326 call "39.84387,-105.05608,39.95133,-104.94827"

Filter

.filter(String)
Accepts a String containing a cql filter. filters can be chained together by repeatedly calling .filter() FIlters will be combined and separated by an AND. If more control is needed over the filter, user .rawFilter()

Raw Filter

.rawFilter(String)
Accepts a complete filter to be passed to the API. When combining individual filters, filters must be surrounded by parenthesis and separated by an AND or OR

SRSName

.srsname(String)
Accepts a string containing the desired projection. Must be set if utilizing a bbox

FeatureID

.featureId(String)
Accepts a string containing the specific feature ID you are looking for. The featureId overrides the .filter method. It will not throw an error if a filter is passed, however the filter will be ignored.

Request Type

.requestType(String)
Accepts a string containing the type of request you want to make. Defaults to "GetFeature" in WFS calls, GetMap in WMS calls and GetTile in WMTS calls

Height

.height(int)
Accepts an integer representing the desired height of the image in pixels. Max 8000. NOTE: 8000px calls may not work due to many factors including server load, user machine capabilities, and latency. For large calls it is recommended the user break the calls up.

Width

.width(int)
Accepts an integer representing the desired width of the image in pixels. Max 8000. NOTE: 8000px calls may not work due to many factors including server load, user machine capabilities, and latency. For large calls it is recommended the user break the calls up.

Image Format

.imageFormat(String)
Accepts a string of the desired format. Supported formats jpeg, geotiff, png.

Download Path

.downloadPath(String)
Accepts a string of the full path of the location to download responses to. Defaults to the users Downloads directory. If a folder that does not exist is declared, then the folder will be created.

Zoom Level

.zoomLevel(int)
Accepts an int representation of the desired zoom level. Supported zoom levels:

  • EPSG:4326
    • 0 - 21
  • EPSG:3857
    • 0 - 31

File Name

.fileName(String)
Accepts a string to represent the desired filename. Defaults to Download.Extension

Legacy ID

.legacyId(String)
Accepts a string representing the legacy identifier you are searching for. Downloads the full image therefore height and width are ignore if they are passed in. Image searches using legacy ID point to api.discover.digitalglobe.com

Band Combination

.bandCombination(ArrayList<String>)
Accepts an ArrayList of Strings containing between 1 - 4 band options.

Thread Number

.threadNumber(int)
Accepts an integer value representing the number of threads to be used for full res download multithreading.

Type Name

.typeName(String)

About

A Java SDK for the Maxar Geospatial Platform

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages