can not create ENC chart

1241
12
04-13-2022 11:55 PM
neddyseagoon
New Contributor

Brand new to ArcGIS, and I'm trying to create an iOS app to display a nautical chart.  I can display a regular chart, I've downloaded a data set, and it's copied to my apps sandboxed documents directory.  However, when I try and load it, the datasets are empty.  I copied the code from the website -- as shown below.  Any help would be greatly appreciated (the dummy string was to simply ensure the correct location is used -- the files are verified present)

thx

        let dummy = "/Users/XXX/Library/Containers/D72BE5E6-A3C3-4718-ADA5-10E2B435BBEB/Data/Documents/ENC_ROOT/CATALOG.031"

        let catalogURL      = URL( fileURLWithPath: dummy /*catalogFile*/ )

        self.encExchangeSet = AGSENCExchangeSet(fileURLs: [catalogURL])

        self.encExchangeSet?.load { [weak self] (error) in

            if let error = error {

                print("Error loading exchange dataset \(error.localizedDescription)")

                return

            }

            self?.encExchangeSet?.datasets.forEach {(dataset) in

 ^^^^self?.encExchangeSet?.datasets is nil

 

0 Kudos
12 Replies
Ting
by Esri Contributor
Esri Contributor

Hi,

Please take a look at the attached example app - I created it based on the Add ENC exchange set sample from iOS Sample Viewer. Plug in your API key and you should be able to see a screen like this 👇

example.png

Please refer to the sample for more details.

A few things to notice

  • ENC charts requires the hydrography dataset to display. You can download it from the link below.
  • S57 hydro data follows a certain folder structure, so when you include it in your project, make sure to either copy the whole folder structure, or use "Create folder references".
  • You'll need to set `AGSENCEnvironmentSettings` before loading the ENC datasets. Check out the example code.

Links

Hope it helps! Let me know if you have further questions, or accept this answer as a solution.

Ting

0 Kudos
neddyseagoon
New Contributor

this is great, thank you.  However, why is the app trying to get online if the ENC files are in the bundle. This is really important as I'm often offline when the boat is moving

thx

0 Kudos
Nicholas-Furness
Esri Regular Contributor

Hi.

The sample loads our global ocean bathymetry basemap for context and displays the ENC chart on top of it, hence the network connection.

That basemap is not necessary and the ArcGIS Runtime can work entirely offline, as you need. You could try changing line 22 in the sample to:

mapView.map = AGSMap(spatialReference: .webMercator())

 Hope that helps!

neddyseagoon
New Contributor

that makes a HUGE difference, thank you!  Effectively what I'm trying to do is to implement a chart plotter (more to it but that's an easy way to describe it) and being offline is extremely important.  

Thank you

0 Kudos
neddyseagoon
New Contributor

So it's working for me with my down data set (pacific north west) but some of the time I only get a relief map and some times the enc chart.  This changes when I run the app not any code changes.  I also can not zoom in very much.  I do have the entire catalog ... which leads me to another question ... this section in the docs ... 

ENC charts are often distributed as base cells (.000 files) with one or more update cells (.001, .002, etc. files). An exchange set can consist exclusively of update cells; in order to load an update exchange set, the path to the base exchange set must be provided along with the path to the update exchange set.

However, my files have .000 .001 .002 etc all mixed in.  As I'm not getting zoomed in views am I doing something else wrong?  Thanks for your help, I'm not finding the docs too clear 🙂

0 Kudos
Nicholas-Furness
Esri Regular Contributor

Hi @neddyseagoon,

It's hard to tell for sure without seeing your data but it's possible that you're doing everything right and the data is just configured not to be visible outside of specific scale ranges?

Are you able to share the data with us? Feel free to DM me if so and we can figure out the best way to get it to us.

0 Kudos
neddyseagoon
New Contributor

right now all I'm trying to do is to display data from a standard NOAA set.  I downloaded the PNW region and so far I'm not using any of my own data.  I *think* you already answered my question as once I could go offline thinks seem to be working better. It does still take a while to come up, like 15 seconds but once the map is up, it's up and works well (I'm running on a M1 MacBook not an iOS device). 

As I have it now, I think all is working except getting a point off the chart. I.e. I would like to be able to get the latitude/longitude/scale of the center of the current viewport, and to be able to translate a mouse position to a latitude longitude.  I don't expect you to fix this for me but can you please point me to the correct place in the docs.  AGSMapView.currentViewportWithType is not it.  (I know everyone learns in different ways but for me, the docs are very confusing).

0 Kudos
Nicholas-Furness
Esri Regular Contributor

Take a look at the sample app. You can download it form the App Store and explore capabilities. Each sample shows the code behind directly in the app, but it's also available on GitHub.

But if you're looking to track the current centerpoint of the map display, you can use AGSMapView.viewpointChangedHandler. You would then want to call AGSMapView.currentViewpointWithType() and pass in .centerAndScale as the type. You'll get an AGSViewpoint back, and look at the targetGeometry. It'll be an AGSPoint that's the center of the map (you'll have to cast to AGSPoint).

The point's coordinates will be in the spatial reference of the map (in this case Web Mercator) which is probably not what you want to output. You'd need to project it to WGS84. We also have a AGSCoordinateFormatter class that can help.

See this code for an example:

 

mapView.viewpointChangedHandler = { [weak self] in
    guard let self = self else { return }
    
    if let center = self.mapView.currentViewpoint(with: .centerAndScale)?.targetGeometry as? AGSPoint {
        // Format the Lat Lon etc. using a standard format
        if let latLonString = AGSCoordinateFormatter.latitudeLongitudeString(from: center, format: .degreesMinutesSeconds, decimalPlaces: 1) {
            print(latLonString)
        }
        
        // Get the coordinates manually…
        if let wgs84center = AGSGeometryEngine.projectGeometry(center, to: .wgs84()) as? AGSPoint {
            print("Lat \(wgs84center.y), Lon \(wgs84center.x)")
        }
    }
}

 

That will output something like this to the Xcode console…

19 56 53.8N 100 32 17.0W

Lat 19.948264571145458, Lon -100.53804579499798

19 58 51.9N 100 42 37.8W

Lat 19.98109671769453, Lon -100.71050437417519

20 00 03.9N 100 48 55.8W

Lat 20.001080434190495, Lon -100.81549113806531

20 00 25.0N 100 50 46.6W

Lat 20.006942571870393, Lon -100.84629108361138

20 00 25.0N 100 50 46.7W

Lat 20.006942719211626, Lon -100.84629185776355

Please note that ENC layers require a Runtime Standard License when you're ready to deploy your app.

0 Kudos
neddyseagoon
New Contributor

this is excellent, thank you.  Do you have any ideas why it takes so long to load the map? (online or offline)

0 Kudos