Underscore

Delphi API 0.1 for ArcGIS Server 10

Discussion created by Underscore on Jun 13, 2012
Latest reply on Aug 15, 2014 by Underscore
Even with auto-save, I still lost my post before submitting.  I worked on it for an hour!

Anyway, I started work on a Delphi API for ArcGIS Server.  What it does is communicate with ArcGIS Server through the REST API using JSON objects.  In Delphi I have classes and types for almost 100 of those ArcGIS objects exposed in the REST API.  If I continue this work, there's lost more to do.

The unit is pretty bad in it's version 0.1 state.  I don't use a lot of memory clean-up, it's poorly documented, and could be organized a lot better.  The thing is, it already does what *I* need it to do, which isn't even the tip of the iceberg.  What I'm asking you guys is if you want me to continue work on the API or not, or perhaps you don't care.

Here is an example that compiles when you add the ArcGISServer unit to the uses clause:

function GoArcGIS( X, Y: Double; Catalog, MapService, MapLayer, FieldName: String ): String;
///  You can try calling this function with the following values:
///  1945785.00909788, 715764.111071926, '',
var
  pConnection: TArcGISServer;
  pGeocodedPt: TAGSPoint;
  pCatalog: TAGSCatalog;
  pMapService: TAGSMapService;
  pBriefLayer: TAGSBriefLayer;
  pMapLayer: TAGSLayerOrTable;
  pQueryResults: TAGSFeatureSet;
  bFound: Boolean;
const
  ServerProtocol = 'http';
  ServerHost = 'sampleserver1.arcgisonline.com';
  ArcGISServerInstance = 'ArcGIS';
begin
  //Initializations to keep the compiler happy since I'm calling Free in the finally clause
  pCatalog := nil;
  pMapService := nil;
  pMapLayer := nil;
  pQueryResults := nil;

  pConnection := TArcGISServer.Create( nil );
  pGeocodedPt := TAGSPoint.Create;
  pGeocodedPt.X := X;
  pGeocodedPt.Y := Y;
  pGeocodedPt.SpatialReference.Wkid := 32043; //NAD 27 Utah Central
  try
    pCatalog := pConnection.GetCatalog( ServerProtocol, ServerHost, ArcGISServerInstance, Catalog );
    if pCatalog = nil then
      Result := ''
    else
    begin
      pMapService := pCatalog.GetMapService( pConnection, MapService );
      if pMapService = nil then
        Result := ''
      else
      begin
        bFound := False;
        for pBriefLayer in pMapService.Layers do
          if not bFound and ( pBriefLayer.Name = MapLayer ) then
          begin
            bFound := True;
            pMapLayer := pMapService.GetLayerOrTable( pConnection, pBriefLayer.Id );
            if pMapLayer = nil then
              Result := ''
            else
            begin
              pQueryResults := pMapLayer.Query( pConnection, '', pGeocodedPt, nil, esriSpatialRelIntersects, '', '', '', FieldName, False );
              if pQueryResults = nil then
                Result := ''
              else
                if pQueryResults.Features.Count = 0 then
                  Result := ''
                else
                  if pQueryResults.Features[ 0 ].Attributes = nil then
                    Result := ''
                  else
                    if not pQueryResults.Features[ 0 ].Attributes.ContainsKey( FieldName ) then
                      Result := ''
                    else
                      Result := pQueryResults.Features[ 0 ].Attributes[ FieldName ];
            end;
          end;
        if not bFound then
          Result := '';
      end;
    end;
  finally
    pConnection.Free;
    pGeocodedPt.Free;
    pCatalog.Free;
    pMapService.Free;
    pMapLayer.Free;
    pQueryResults.Free;
  end;
end;


If you call the above function with these values, you should get the value Utah, since the provided point is Orem's City Center, which is in Utah County of the state of Utah.
GoArcGIS( 1945785.00909788, 715764.111071926, 'Specialty', 'ESRI_StateCityHighway_USA', 'counties', 'NAME' );


Because it's Delphi code, you could easily make a Desktop application that harnesses ArcGIS Server's REST API, or a Web Broker application, or a DLL, or an ActiveX component, or some VCL components, or whatever else you wanted with Delphi's IDE.  The trick is that you should have a fairly current version of Delphi (I wrote it in XE2) and you should have the Enterprise version, since JSON object units don't exist in the Professional version (or so I'm told).

Let me know what you guys think.  Also, I really want to get back to documenting how to create ActiveX components for use inside ArcGIS Desktop programs with Delphi XE2.  But there is yet another COM bug in Delphi that prevents it from compiling correctly, specifically bug QC 104063.

"Roj"

Attachments

Outcomes