[DotNet] Is it possible to create an elevation  Profile layer using Arc Engine

2329
6
Jump to solution
03-12-2012 05:05 AM
ManfredLauterbach
Occasional Contributor
Greetings,

I am upgrading a stand alone application (from MapObjects 2.2), to ArcObjects 10 in DotNet.
MapObjects did not support a dynamic Terrain Profile view - this feature was added manually (using windows Forms and custom elevation data processing).

The input data is in the form of SRTM elevation files (http://en.wikipedia.org/wiki/Shuttle_Radar_Topography_Mission).
The objective is to dynamically enable / disable a layer or view of an elevation profile for a given path over elevation data (i.e. set of lat/lon coordinates).

The image below is an example (click to enlarge):
[ATTACH=CONFIG]12587[/ATTACH]

After a lot of reading and searching the ArcGIS forums I understand that the spacial analyst extension seems to be the correct extension for this feature - but I cannot find any references in the API for what I would like to do : create an elevation profile image from elevation data.
I also see that ARC Desktop has front end features to manage this sort of visualization - but I would like to do this programmatically with ArcEngine in my own stand alone application.
It would obviously be ideal if ArcEngine itself could handle this, without the need for an extension.

The ESRI sales consultant explained to us that this would certainly be possible - could someone please point me in the right direction.
Thanks.
0 Kudos
1 Solution

Accepted Solutions
NeilClemmons
Regular Contributor III
The help states that the class requires the 3d Analyst extension.  That's different than requiring a 3d Analyst license.  Not all of the objects in the 3d Analyst assemblies require any special licensing but in order to access and use them the assemblies for the extension must be installed.  I'm not very familiar with Engine as I don't use it much so I don't know if those assemblies are installed as part of the core product or not.  If they are, then I would say you don't have much need to worry.

When I first began programming with ArcObjects there weren't any resources to help developers like there are today - online resources website, sample code, tech articles, walkthroughs, etc.  The developer help was just a *.chm file that contained nothing more than an inventory of the interfaces, classes, methods, etc.  It didn't have any comments, remarks, guidance, etc. to help developers figure out how to use any of the ArcObjects classes.  So, yes, it was difficult.  What made it even worse was the fact that there were many more bugs in the software than there are today.  So, many times I would be trying to figure out how to get something to work only to find out after several days that my code had been correct all along and it wasn't working because of a bug in the ESRI code.  After you've worked with the ArcObjects object model for awhile, things get much easier.  The biggest hurdle most developers face is simply not knowing what interfaces and classes they need to be using for a specific task.  Once you get familiar with ESRI terminology and naming conventions you tend to find those things a lot quicker.  It also helps if you have a good memory.  In the beginning I did a lot of searching through that skeleton help document and in doing so I read the names of a lot of interfaces and classes.  Later on, when faced with a new task I'd remember seeing things that sounded like what I might need for that new task.  The ArcObjects library is huge.  I don't know what the count is up to now but at one time I believe the number of interfaces, classes, enums, etc. was around 30,000.  It just takes time to get familiar with all of that.  Using Google and the ESRI help site is the best way to find what you need.  I would also recommend going to the old user forums and searching there first (I don't think the current search includes those forums).  There's a decades worth of information on the old forums and while most of the code you'll find will be in VB6/VBA, I think it'll help.  The key is figuring out the keywords to search with.  You'll get better at that as you go.

And, I don't think you'll be able to use IDataGraphT.  A good rule of thumb, if it comes from an assembly whose name ends with "UI", it's Desktop only.  Sorry, I should have caught that.  You'll have to use a 3rd party graphing control or use the native Microsoft libraries like you mentioned.

View solution in original post

0 Kudos
6 Replies
NeilClemmons
Regular Contributor III
Yes, it's possible.  The basic process would be to get the functional surface (ISurface) from your elevation layer, get/create a polyline (IPolyline) object that the profile should be based on, interpolate z-values for the polyline (ISurface.InterpolateShape) or call ISurface.GetProfile and then graph it.  You can use the built-in graph objects (IDataGraphT) or use a 3rd party graphing library to display the profile graph.
0 Kudos
ManfredLauterbach
Occasional Contributor
Thanks for the initial guidance.

I would like to implement what you mentioned but am unable to find a way to load .hgt files (STRM data), using ArcEngine - I can read them in manually (with dotnet code), but would like to create a dataset from the data using ArcObjects in order to reach the next step.
Created another thread for this : http://forums.arcgis.com/threads/52752-ArcEngine-DotNet-How-to-load-.hgt-files-into-a-dataset-and-th... in order to proceed.
0 Kudos
ManfredLauterbach
Occasional Contributor
ok. Thanks to http://forums.arcgis.com/threads/52752-ArcEngine-DotNet-How-to-load-.hgt-files-into-a-dataset-and-th... we now have a fully functional RasterDataset and RasterLayer, which were successfully tested with a RasterRenderer (UniqueValueRenderer) to display the SRTM height map on a map control. Excellent.

Moving right along, your suggestion was to create a surface from the said layer.
Taking a closer look at ISurface, it implements only RasterSurface and Tin.
RasterSurface requires the 3DAnalyst extension (having to buy 3DAnalyst just for the terrain profile would be a bit unreasonable), and Tin requires the associated factory and workspace boilerplate architecture - which only reads in existing tin files.

Is there any other sort of dedicated elevation profile interface which accepts raster elevation data as input?
0 Kudos
NeilClemmons
Regular Contributor III
I don't think you need any additional licensing to do this.  I just ran the following VBA code in ArcMap 9.3.1 with all of my extensions turned off and it worked.

Sub profileTest()
    Dim mxDocument As IMxDocument
    Set mxDocument = ThisDocument
    Dim rasterLayer As IRasterLayer
    Set rasterLayer = mxDocument.FocusMap.layer(7)
   
    Dim surface As ISurface
    Set surface = GetSurfaceFromLayer(rasterLayer)
   
    Dim fromPoint As IPoint
    Set fromPoint = New point
    fromPoint.PutCoords 286000, 4271200
   
    Dim toPoint As IPoint
    Set toPoint = New point
    toPoint.PutCoords 286500, 4271200
   
    Dim polyline As IPolyline
    Set polyline = New polyline
    polyline.fromPoint = fromPoint
    polyline.toPoint = toPoint
   
    surface.GetProfile polyline, polyline
   
    Dim pointCollection As IPointCollection
    Set pointCollection = polyline
    Dim i As Long
    For i = 0 To pointCollection.PointCount - 1
        Dim point As IPoint
        Set point = pointCollection.point(i)
        MsgBox point.X & ", " & point.Y & ", " & point.Z
    Next i
End Sub

Function GetSurfaceFromLayer(rasterLayer As IRasterLayer) As ISurface
    Dim surface As ISurface
   
    Dim layerExtensions As ILayerExtensions
    Set layerExtensions = rasterLayer
    Dim i As Long
    For i = 0 To layerExtensions.ExtensionCount - 1
        Dim dddProperties As I3DProperties
        Set dddProperties = layerExtensions.Extension(i)
        If dddProperties.BaseOption = esriBaseSurface Then
            Set surface = dddProperties.BaseSurface
        End If
    Next
   
    If surface Is Nothing Then
        Dim rasterBandCollection As IRasterBandCollection
        Set rasterBandCollection = rasterLayer.Raster
        Dim rasterBand As IRasterBand
        Set rasterBand = rasterBandCollection.Item(0)
        Dim rasterSurface As IRasterSurface
        Set rasterSurface = New rasterSurface
        rasterSurface.rasterBand = rasterBand
        Set surface = rasterSurface
    End If
   
    Set GetSurfaceFromLayer = surface
End Function
0 Kudos
ManfredLauterbach
Occasional Contributor
Thanks Neil - that certainly does work despite the stated requirement for 3DAnalyst (http://help.arcgis.com/en/sdk/10.0/arcobjects_net/componenthelp/index.html#/RasterSurfaceClass_Class...) - which concerns me enough not to use this as a permanent solution.

[rant]
before continuing, could you please give me an honest opinion : I see you've been working with ArcObjects for at least 10 years now? - Did you experience the same difficulty trying to implement new features as I am now? Having worked in the application development industry for almost 10 years myself I certainly don't consider myself a blundering novice either - yet I find myself being incredibly frustrated by the amount of time I have to spend trying to search and sift through documentation and reply on forum support in order to accomplish something with ArcEngine... am I doing something wrong? If half my answers are coming from experienced developers or architects that have worked with ArcObjects before then perhaps I'm missing something important.
[/rant]

Back to the problem at hand:
Also tried to implement IDataGraphT as you mentioned earlier, but ran into some confusing information:
http://help.arcgis.com/en/sdk/10.0/arcobjects_net/componenthelp/index.html#//00120000034p000000 states that IDataGraphT is supported by ArcEngine...
http://help.arcgis.com/en/sdk/10.0/arcobjects_net/conceptualhelp/index.html#//00010000013w000000 states that a license for ArcView, ArcEditor or ArcInfo is required (no mention of ArcEngine) - the sample also shows an ArcView license being initialized in order to proceed.
My own code is obviously initializing ArcEngine and fails as soon as I try to instantiate DataGraphT.

IDataGraphT dataGraphT = new DataGraphTClass();

"Retrieving the COM class factory for component with CLSID {58B570A4-02AE-44FC-B36F-630AE32EA4E4} failed due to the following error: 80040154 Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG))."

Either way, producing a polyline with height values from the raster dataset is already a huge step forward (can use this for an terrain elevation overlay).
If there are no other means of creating a terrain profile as shown in the picture in the first post, then I'll have to stick with drawing everything manually using Windows GDI (as with Map Objects).
Thanks again for the support.
0 Kudos
NeilClemmons
Regular Contributor III
The help states that the class requires the 3d Analyst extension.  That's different than requiring a 3d Analyst license.  Not all of the objects in the 3d Analyst assemblies require any special licensing but in order to access and use them the assemblies for the extension must be installed.  I'm not very familiar with Engine as I don't use it much so I don't know if those assemblies are installed as part of the core product or not.  If they are, then I would say you don't have much need to worry.

When I first began programming with ArcObjects there weren't any resources to help developers like there are today - online resources website, sample code, tech articles, walkthroughs, etc.  The developer help was just a *.chm file that contained nothing more than an inventory of the interfaces, classes, methods, etc.  It didn't have any comments, remarks, guidance, etc. to help developers figure out how to use any of the ArcObjects classes.  So, yes, it was difficult.  What made it even worse was the fact that there were many more bugs in the software than there are today.  So, many times I would be trying to figure out how to get something to work only to find out after several days that my code had been correct all along and it wasn't working because of a bug in the ESRI code.  After you've worked with the ArcObjects object model for awhile, things get much easier.  The biggest hurdle most developers face is simply not knowing what interfaces and classes they need to be using for a specific task.  Once you get familiar with ESRI terminology and naming conventions you tend to find those things a lot quicker.  It also helps if you have a good memory.  In the beginning I did a lot of searching through that skeleton help document and in doing so I read the names of a lot of interfaces and classes.  Later on, when faced with a new task I'd remember seeing things that sounded like what I might need for that new task.  The ArcObjects library is huge.  I don't know what the count is up to now but at one time I believe the number of interfaces, classes, enums, etc. was around 30,000.  It just takes time to get familiar with all of that.  Using Google and the ESRI help site is the best way to find what you need.  I would also recommend going to the old user forums and searching there first (I don't think the current search includes those forums).  There's a decades worth of information on the old forums and while most of the code you'll find will be in VB6/VBA, I think it'll help.  The key is figuring out the keywords to search with.  You'll get better at that as you go.

And, I don't think you'll be able to use IDataGraphT.  A good rule of thumb, if it comes from an assembly whose name ends with "UI", it's Desktop only.  Sorry, I should have caught that.  You'll have to use a 3rd party graphing control or use the native Microsoft libraries like you mentioned.

View solution in original post

0 Kudos