This is an ongoing project, and the results will be published upon its completion. As a result, no GIS results are discussed.
This project requires viewing lakes on imageries provided by Google, Esri and Microsoft Bing for stress analysis. Esri and Bing imageries can be added directly to ArcMap as basemap layers. Basin and lakes layers can be added to ArcMap, thus these lakes can be visually inspected against the backdrop of Esri and Bing basemaps. This way while working in ArcMap, we can inspect each lake feature by zooming in and analyzing them in context of imageries basemap. Note that even this way, Bing maps take rather longer time to display. This could be probably because Bing maps zoom to predefined resolution levels seen as notches on the zoom scale, but ArcMap can zoom to any arbitrary scale of resolution so it resamples to the resolution of display causing delays in rendering.
Unfortunately, Google imageries cannot be added as another basemap layer to ArcMap. So, an alternative method is needed to inspect lakes on Google imageries. One of the methods is to launch Google Earth, and then enter coordinates (latitude, longitude) of the lake and then zoom to that location. To do this for thousands of lakes is cumbersome, and error prone. A better approach is needed. I was able to find a script at esri’s website supplied by third party for free that tries to address this situation. The tool is available at URL http://arcscripts.esri.com/details.asp?dbid=16083. It was written for earlier versions of ArcGIS, so I modified it to run on ArcGIS 10.
The goal is to execute some JavaScript function embedded inside an HTML page hosted by Internet Browser from a VBA application. This is similar to the following scenario. Imagine that we have a button on the HTML page which is attached to a JavaScript function which gets activated when the button is clicked. We have a VBA application that we want to use to launch the HTML page in Internet Explorer, and then click on the button from the VBA code automatically. That is, the button on the HTML page got clicked as if a user was doing it, but in reality it is performed by the VBA code written for a User Interface (UI) tool in ArcMap. How do we do it? The following code sample demonstrates it.
JavaScript Code in HTML Page:
<input type = "button" value="Button on HTML Page" onclick="javascript: MyFunction('MyValue');">
VBA Code for ArcMap UI tool
In the VBA code, insert the following line wherever you want to click on the button. The Document object can be obtained from Internet Explorer Application object.
IE = CreateObject(“InternetExplorer.Application”)
Document = IE.Document
Call Document.parentWindow.execScript("MyFunction ('MyValue');")
In this study, we use this approach except that we do not have a button, but instead we have a map refresh event to which we will attach the code. As explained, the basic idea is to make use of the fact that we can launch a piece of code (script) written in JavaScript that is part of a HTML page running in an independent web browser from ArcMap. The code in ArcMap is written in VBA (Visual Basic for Applications), and it is attached to the map extent change event. Thus, every time the map extent changes, such as triggered by zoom action, the VBA code in ArcMap passes the map extent coordinates to javascript (that is actually a part of an HTML page). The web browser showing the HTML page executes the JavaScript code to launch Google Earth and zooms to the passed map extent. Thus, we can keep ArcMap and a web browser applications running side by side on separate computer monitors, and can view features such as lake and basins in ArcMap and Google Earth (in a web browser) simultaneously. This approach prevents ArcMap from getting overwhelmed with basemap displays (such as Bing), and is very fast and efficient. It also offers an efficient way to compare imageries from Bing and Google side by side.
This approach requires Google Earth installed on the computer. ArcGIS 10 was used in this study, and it requires VBA (Visual Basic for Applications) license activated. The VBA license is not active at ArcGIS 10 by default, but it is available for free from Esri. The VBA code for ArcMap, and HTML page with JavaScript code is shown below. As discussed above, the KML files for lakes are not published because they are part of an ongoing research.
It has the a HTML and VBA file. Download both the files in a zipped file. Extract the HTML file and copy it to the disk. Open the VBA code in Notepad, and edit to change the location of HTML file to point to the location where you copied it. Look for the function UIToolControl1_Select in VBA code, and edit the following line to reflect the location of HTML file on disk. This is where in VBA you need to make changes:
Private Sub UIToolControl1_Select() ' this is the function
m_pIE.navigate2 "file://C:\Users\Desktop\GE_ArcGIS\test\SalineLakes.htm"
-------------------------------------------------------------------
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <head> <!-- Copyright 2008 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <title>Hello Google Earth!</title> <!-- *** Replace the key below below with your own API key, available at http://code.google.com/apis/maps/signup.html *** --> <script src="http://www.google.com/jsapi?key=ABQIAAAAwbkbZLyhsmTCWXbTcjbgbRSzHs7K5SvaUdm8ua-Xxy_-2dYwMxQMhnagaawTo7L1FE1-amhuQxIlXw"></script> <script> google.load("earth", "1"); var ge = null; function init() { google.earth.createInstance("map3d", initCallback, failureCallback); } function initCallback(object) { ge = object; ge.getWindow().setVisibility(true); ge.getNavigationControl().setVisibility(ge.VISIBILITY_SHOW); ge.getLayerRoot().enableLayerById(ge.LAYER_BORDERS, true); ge.getLayerRoot().enableLayerById(ge.LAYER_ROADS, true); var link = ge.createLink(''); var href = 'https://sites.../SelectedLakes.kmz' //lakes link.setHref(href); var networkLink = ge.createNetworkLink(''); networkLink.set(link, true, false); // Sets the link, refreshVisibility, and flyToView ge.getFeatures().appendChild(networkLink); link = ge.createLink(''); href = 'https://sites..../SelectedBasins.kmz' //basin link.setHref(href); networkLink = ge.createNetworkLink(''); networkLink.set(link, true, false); // Sets the link, refreshVisibility, and flyToView ge.getFeatures().appendChild(networkLink); } function ZoomTo(lon,lat,z) { var cam = ge.getView().copyAsCamera(ge.ALTITUDE_ABSOLUTE); cam.setLongitude(lon); cam.setLatitude(lat); cam.setAltitude(z) ge.getView().setAbstractView(cam); } function query() { var la = ge.getView().copyAsLookAt(ge.ALTITUDE_RELATIVE_TO_GROUND); var cam = ge.getView().copyAsCamera(ge.ALTITUDE_ABSOLUTE); alert(cam.getAltitude()) } function failureCallback(object) { } </script> </head> <body onload='init()' id='body'> <center> <div> Assessing Lakes, UCLA </div> <div id='map3d' style="position: absolute; left: 0px; top: 0px; width: 100%; height: 100%;"></div> </center> </body> </html>
--------------------------------------------------------------
Users will need to built an ArcMap UI tool and attach the VBA code shown below.
'VBA Code for Macro in ArcMap
Private WithEvents m_pMap As Map
Private m_pIE As Object
Private Sub m_pMap_ViewRefreshed(ByVal view As esriCarto.IActiveView, ByVal
phase As esriCarto.esriViewDrawPhase, ByVal Data As Variant, ByVal envelope As
esriGeometry.IEnvelope)
On Error GoTo EH
Dim pPoint As IPoint
Set pPoint = New Point
pPoint.X = (view.Extent.XMax + view.Extent.XMin) / 2
pPoint.Y = (view.Extent.YMax + view.Extent.YMin) / 2
Dim lat As Double
Dim lon As Double
Dim pMxDoc As IMxDocument
Set pMxDoc = ThisDocument
PointToLatLon pMxDoc, pPoint, lat, lon
Dim n As Double
n = Round(pMxDoc.FocusMap.MapScale) / 5.82
m_pIE.Document.parentWindow.execScript "ZoomTo(" & lat & "," & lon & "," & n
& ");", "javascript"
Exit Sub
EH:
Debug.Print "Error: " & Err.Description
End Sub
Function PointToLatLon(pMxDocument As IMxDocument, ByVal pPoint As IPoint, ByRef
dLatitude As Double, ByRef dLongitude As Double)
On Error GoTo EH:
' variables for dealing with projections and units
Dim pSpRefOutput As esriGeometry.ISpatialReference
Dim pSpRefInput As esriGeometry.ISpatialReference
' set the spatial reference of output KML data
Dim pSpRFc As esriGeometry.SpatialReferenceEnvironment
Dim pGCS As esriGeometry.IGeographicCoordinateSystem
Set pSpRFc = New esriGeometry.SpatialReferenceEnvironment
Set pGCS = pSpRFc.CreateGeographicCoordinateSystem(esriSRGeoCS_WGS1984)
Set pSpRefOutput = pGCS
pSpRefOutput.SetFalseOriginAndUnits -180, -90, 1000000
Dim pGeometry2 As IGeometry2
Set pGeometry2 = pPoint
Set pSpRefInput = pMxDocument.FocusMap.SpatialReference
' project feature into latitude/longtitude if necessary
Set pGeometry2.SpatialReference = pSpRefInput
pGeometry2.Project pSpRefOutput
Dim pNewPoint As IPoint
Set pNewPoint = pGeometry2
dLatitude = pNewPoint.X
dLongitude = pNewPoint.Y
Exit Function
EH:
Debug.Print "Error: " & Err.Description
End Function
Private Sub UIToolControl1_Select()
On Error GoTo EH:
Dim pMxDoc As IMxDocument
Set pMxDoc = ThisDocument
Set m_pMap = pMxDoc.FocusMap
Set m_pIE = CreateObject("InternetExplorer.Application")
m_pIE.Visible = True
m_pIE.navigate2 "file://C:\Users\Desktop\GE_ArcGIS\test\Ge.htm"
Exit Sub
EH:
Debug.Print "Error: " & Err.Description
End Sub
No comments:
Post a Comment