1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
|
Attribute VB_Name = "ImageMapWorker"
Public Sub ExportImage(dir As String, base As String, Dpi As Double, imgformat As String)
LoggerForm.appendLog ("Exporting image...")
Dim pMxDoc As IMxDocument
Set pMxDoc = ThisDocument
Dim pActiveView As IActiveView
Dim pExporter As IExport
Dim pEnv As IEnvelope
Set pActiveView = pMxDoc.ActiveView
If imgformat = "PNG" Then Set pExporter = New ExportPNG
If imgformat = "JPEG" Then Set pExporter = New ExportJPEG
Set pEnv = New Envelope
Dim screenDpi As Double
Dim exportFrame As tagRECT
screenDpi = 92
With exportFrame
.Right = 0
.Top = 0
.Right = pActiveView.exportFrame.Right * (Dpi / screenDpi)
.bottom = pActiveView.exportFrame.bottom * (Dpi / screenDpi)
End With
pEnv.PutCoords exportFrame.Left, exportFrame.Top, exportFrame.Right, exportFrame.bottom
With pExporter
.PixelBounds = pEnv
.ExportFileName = PathCombine(dir, base & "." & LCase(imgformat))
End With
Dim hdc As Long
hdc = pExporter.StartExporting
pActiveView.Output hdc, Dpi, exportFrame, Nothing, Nothing
pExporter.FinishExporting
LoggerForm.appendLog ("Done exporting image.")
End Sub
Public Sub ExportImageMap(dir As String, base As String, Dpi As Integer, simpliFact As Double, _
iHref As String, iTitle As String, iName As String, iId As String, _
lyrIndices As Collection, imgformat As String)
LoggerForm.appendLog ("Exporting image map...")
Dim pMxDoc As IMxDocument
Set pMxDoc = ThisDocument
Dim devEnv As IEnvelope
Dim exportFrame As tagRECT
exportFrame = pMxDoc.ActiveView.exportFrame
Set devEnv = New Envelope
With exportFrame
.Left = 0
.Top = 0
.Right = CInt(pMxDoc.ActiveView.exportFrame.Right * (Dpi / 92))
.bottom = CInt(pMxDoc.ActiveView.exportFrame.bottom * (Dpi / 92))
End With
devEnv.PutCoords exportFrame.Left, exportFrame.Top, _
exportFrame.Right, exportFrame.bottom
Dim pMapFrame As IMapFrame
Dim pGC As IGraphicsContainer
Dim mapEnv As IEnvelope
Set pGC = pMxDoc.ActiveView
Set pMapFrame = pGC.FindFrame(pMxDoc.FocusMap)
Set mapEnv = pMapFrame.MapBounds
Dim txtimapStart As String
Dim txtimapEnd As String
foreHTML = "<html><body><map name='arcmap'>"
tailHTML = "</map><img src='" & base & "." & LCase(imgformat) & "' border='0' alt='Map' usemap='#arcmap'></body></html>"
Dim fnum As Integer
Dim path As String
fnum = FreeFile
path = PathCombine(dir, base & ".html")
Open path For Output As #fnum
Print #fnum, foreHTML
Dim layerSet As ISet
Dim piLayer As IFeatureSelection
Dim piFLayer As IFeatureLayer
Dim pFeatureSelection As IFeatureSelection
Dim pSelectionSet As ISelectionSet
Dim pFeatureCursor As IFeatureCursor
Dim pFeature As IFeature
Dim index As Variant
For Each index In lyrIndices
Set piLayer = pMxDoc.ActiveView.FocusMap.Layer(index)
Set piFLayer = piLayer
Set pFeatureSelection = piLayer
Set pSelectionSet = pFeatureSelection.SelectionSet
pSelectionSet.Search Nothing, False, pFeatureCursor
If pSelectionSet.Count = 0 Then
Set pFeatureCursor = piFLayer.FeatureClass.Search(Nothing, False)
End If
Set pFeature = pFeatureCursor.NextFeature
Dim tmpEnv As IEnvelope
Dim trPoints As IPointCollection
Dim areaTag As String
Dim txtCoord As String
Do Until pFeature Is Nothing
Set tmpEnv = mapEnv.Envelope
pFeature.Shape.Project tmpEnv.SpatialReference
tmpEnv.Intersect pFeature.Extent
If Not (tmpEnv.IsEmpty) Then
Dim pGeomColl As IGeometryCollection
Dim GeometryCount As Integer
Set pGeomColl = pFeature.Shape
For GeometryCount = 0 To pGeomColl.GeometryCount - 1
Set trPoints = transformPC(pGeomColl.Geometry(GeometryCount), mapEnv, devEnv)
Set trPoints = simplifyPC(trPoints, simpliFact)
If trPoints.PointCount >= 6 Then
txtCoord = PointCollAsString(trPoints, 0)
areaTag = "<area shape='poly'"
If iHref <> "" Then
If pFeature.Table.FindField(iHref) <> -1 Then
areaTag = areaTag & " href='" & _
pFeature.Value(pFeature.Table.FindField(iHref)) & "'"
End If
End If
If iTitle <> "" Then
If pFeature.Table.FindField(iTitle) <> -1 Then
areaTag = areaTag & " title='" & _
pFeature.Value(pFeature.Table.FindField(iTitle)) & "' alt='" & _
pFeature.Value(pFeature.Table.FindField(iTitle)) & "'"
End If
End If
If iName <> "" Then
If pFeature.Table.FindField(iName) <> -1 Then
areaTag = areaTag & " name='" & _
pFeature.Value(pFeature.Table.FindField(iName)) & "'"
End If
End If
If iId <> "" Then
If pFeature.Table.FindField(iId) <> -1 Then
areaTag = areaTag & " id='" & _
pFeature.Value(pFeature.Table.FindField(iId)) & "'"
End If
End If
areaTag = areaTag & " coords='" & txtCoord & "'"
areaTag = areaTag & "/>"
Print #fnum, areaTag
End If
DoEvents
Next GeometryCount
End If
Set pFeature = pFeatureCursor.NextFeature
Loop
Next index
Print #fnum, tailHTML
Close #fnum
LoggerForm.appendLog ("Done exporting image map.")
End Sub
Private Function transformPC(points As IPointCollection, mapEnv As IEnvelope, devEnv As IEnvelope) As IPointCollection
Dim parsedPoints As Scripting.Dictionary
Dim trPoints As IPointCollection
Dim pPt As IPoint
Dim X As Long, Y As Long
Dim i As Integer
Dim hash As Double
Set parsedPoints = New Scripting.Dictionary
Set trPoints = New esriCore.Polygon
For i = 0 To points.PointCount - 1
X = devEnv.width * ((points.Point(i).X - mapEnv.xMin) / mapEnv.width)
Y = devEnv.height * ((mapEnv.yMax - points.Point(i).Y) / mapEnv.height)
If X < devEnv.xMin Then X = devEnv.xMin
If X > devEnv.xMax Then X = devEnv.xMax
If Y < devEnv.yMin Then Y = devEnv.yMin
If Y > devEnv.yMax Then Y = devEnv.yMax
hash = 18269 * X + 10061 * Y
If Not parsedPoints.Exists(hash) = True Then
Set pPt = New esriCore.Point
pPt.X = X
pPt.Y = Y
trPoints.AddPoint pPt
parsedPoints.Add hash, True
End If
Next i
Set transformPC = trPoints
End Function
Private Function simplifyPC(points As IPointCollection, simpliFact As Double) As IPointCollection
If points.PointCount < 5 Then
Set simplifyPC = points
Exit Function
End If
Dim pt As IPoint
Dim ii As Long
Dim dist As Double
Dim minDist As Double
points.AddPoint points.Point(0)
dist = 0
For ii = 0 To points.PointCount - 2
dist = Sqr((points.Point(ii + 1).X - points.Point(ii).X) ^ 2 + _
(points.Point(ii + 1).Y - points.Point(ii).Y) ^ 2)
Next ii
minDist = simpliFact / 10 / log(5 + dist / (points.PointCount - 2))
Dim jj As Long
ii = 0
dist = 0
Do
jj = ii + 1
If jj >= points.PointCount - 1 Then Exit Do
Do
dist = Sqr((points.Point(jj).X - points.Point(ii).X) ^ 2 + _
(points.Point(jj).Y - points.Point(ii).Y) ^ 2)
If dist < minDist Then
points.RemovePoints jj, 1 Else
Exit Do
End If
If jj >= points.PointCount - 1 Then Exit Do
DoEvents
Loop
ii = ii + 1
DoEvents
Loop
points.RemovePoints points.PointCount - 1, 1 Set simplifyPC = points
End Function
Private Function calcArea(p1 As IPoint, p2 As IPoint, p3 As IPoint) As Double
calcArea = 1 / 2 * (-p2.X * p1.Y + p3.X * p1.Y + _
p1.X * p2.Y - p3.X * p2.Y - p1.X * p3.Y + p2.X + p3.Y)
End Function
Private Function PointCollAsString(pPC As IPointCollection, lFormatNum As Long) As String
Dim pPt As IPoint
Dim strCollection As String, strPoint As String
Dim i As Long
For i = 0 To pPC.PointCount - 1
Set pPt = pPC.Point(i)
strPoint = PointAsString(pPt, 0)
If strCollection <> "" Then
strCollection = strCollection & ", " & strPoint
Else
strCollection = strCollection & strPoint
End If
Set pPt = Nothing
Next i
PointCollAsString = strCollection
End Function
Private Function PointAsString(pPt As IPoint, lFormatNum As Long) As String
Dim strFormat As String
Dim strXCoord As String, strYCoord As String
If lFormatNum = 0 Then
strFormat = "#0"
Else
strFormat = "#0."
Dim i As Long
For i = 0 To lFormatNum - 1
strFormat = strFormat & "0"
Next i
End If
strXCoord = Format(CStr(Round(pPt.X, lFormatNum)), strFormat)
strYCoord = Format(CStr(Round(pPt.Y, lFormatNum)), strFormat)
PointAsString = strXCoord & "," & strYCoord
End Function
Private Function PathCombine(path1 As String, path2 As String) As String
If Right(path1, 1) <> "\" And Left(path2, 1) <> "\" Then
PathCombinePath = path1 & "\" & path2
Exit Function
End If
If Right(path1, 1) = "\" And Left(path2, 1) = "\" Then
PathCombinePath = Left(path1, Len(path1) - 1) & _
"\" & Right(path2, Len(path2) - 1)
Exit Function
End If
PathCombine = path1 & path2
End Function
|