ArcGIS.Server.9.2.DotNet自带例子分析(一、四)
目的:
1.距离测量功能。
准备:
1.(一、三)的工程,具体见前篇。
开始:
1.新建名为Measure.ascx的用户控件,并且实现ICallbackEventHandler接口,具体代码如下:
3.代码贴太多了编辑器死掉了一样了,郁闷换个新篇继续写了...
1.距离测量功能。
准备:
1.(一、三)的工程,具体见前篇。
开始:
1.新建名为Measure.ascx的用户控件,并且实现ICallbackEventHandler接口,具体代码如下:
1
namespace MappingApp
2
{
3
public partial class Measure : System.Web.UI.UserControl, ICallbackEventHandler
4
{
5
protected void Page_Load(object sender, EventArgs e)
6
{
7
8
}
9
10
ICallbackEventHandler 成员
25
}
26
}
2. 加入具体的线距离测量和面积测量功能代码,具体的代码和说明如下:
2

3

4

5

6

7

8

9

10

25

26

1
namespace MappingApp
2
{
3
//地图单位
4
public enum MapUnit
5
{
6
Resource_Default, Degrees, Feet, Meters //默认,度,码,米
7
}
8
9
//测量单位
10
public enum MeasureUnit
11
{
12
Feet, Kilometers, Meters, Miles //码,千米,米,英里
13
}
14
15
//区域单位
16
public enum AreaUnit
17
{
18
Acres, Sq_Feet, Sq_Kilometers, Sq_Meters, Sq_Miles //英亩,平方码,平方千米,平方米,平方英里
19
}
20
21
public partial class Measure : System.Web.UI.UserControl, ICallbackEventHandler
22
{
23
MapResourceManager m_resourceManger;
24
IMapFunctionality m_mapFunctionality;
25
//页面
26
private Page m_page;
27
//客户端代码段
28
public string m_callbackInvocation = "";
29
//地图控件ID
30
private string m_mapBuddyId = "Map1";
31
//用户控件id
32
public string m_id;
33
//地图控件
34
private Map m_map;
35
//默认地图单位
36
private MapUnit m_FallbackMapUnit = MapUnit.Degrees;
37
private MapUnit m_mapUnits;
38
//
39
private MapUnit m_startMapUnits = MapUnit.Degrees;
40
//默认测量单位
41
public MeasureUnit m_measureUnits = MeasureUnit.Miles;
42
//默认区域单位
43
public AreaUnit m_areaUnits = AreaUnit.Sq_Miles;
44
//数字精确到4位
45
private double m_numberDecimals = 4;
46
47
protected void Page_Load(object sender, EventArgs e)
48
{
49
//控件id
50
m_id = this.ClientID;
51
//页面
52
m_page = this.Page;
53
if (m_mapBuddyId == null || m_mapBuddyId.Length == 0)
54
{
55
m_mapBuddyId = "Map1";
56
}
57
//获取map控件
58
m_map = m_page.FindControl(m_mapBuddyId) as Map;
59
//获取MapResourceManager控件
60
m_resourceManger = m_page.FindControl(m_map.MapResourceManager) as MapResourceManager;
61
//通过GetCallbackEventReference生成客户端调用的javascript方法段
62
m_callbackInvocation = m_page.ClientScript.GetCallbackEventReference(this, "argument", "processCallbackResult", "context", true);
63
}
64
65
//
66
protected void Page_PreRender(object sender, EventArgs e)
67
{
68
GetMeasureResource();
69
}
70
71
private void GetMeasureResource()
72
{
73
string primeResource = m_map.PrimaryMapResource;
74
IEnumerable mapResources = m_resourceManger.GetResources();
75
IEnumerator resEnum = mapResources.GetEnumerator();
76
77
resEnum.MoveNext();
78
79
IGISResource resource;
80
if (primeResource != null && primeResource.Length > 0)
81
{
82
resource = m_resourceManger.GetResource(primeResource);
83
}
84
else
85
{
86
resource = resEnum.Current as IGISResource;
87
}
88
89
if (resource != null)
90
{
91
m_mapFunctionality = (IMapFunctionality)resource.CreateFunctionality(typeof(IMapFunctionality), "mapFunctionality");
92
}
93
}
94
95
ICallbackEventHandler 成员
163
164
//根据请求字符串进行不同的测量
165
public string ProcessMeasureRequest(NameValueCollection queryString)
166
{
167
if (m_mapFunctionality == null)
168
{
169
GetMeasureResource();
170
}
171
object o = Session["MeasureMapUnits"];
172
if (o != null)
173
{
174
m_mapUnits = (MapUnit)Enum.Parse(typeof(MapUnit), o.ToString());
175
}
176
else if (m_startMapUnits == MapUnit.Resource_Default)
177
{
178
//获取默认地图单位
179
m_mapUnits = GetResourceDefaultMapUnit();
180
}
181
else
182
{
183
m_mapUnits = m_startMapUnits;
184
}
185
186
//请求参数
187
string eventArg = queryString["EventArg"].ToLower();
188
string vectorAction = queryString["VectorAction"].ToLower();
189
string[] coordPairs, xys;
190
//坐标字符串
191
string coordString = queryString["coords"];
192
if (coordString == null && coordString.Length == 0)
193
{
194
coordString = "";
195
}
196
//坐标字符串分割
197
coordPairs = coordString.Split(char.Parse("|"));
198
//地图单位
199
string mapUnitString = queryString["MapUnits"];
200
if (mapUnitString != null && mapUnitString.Length > 0)
201
{
202
m_mapUnits = (MapUnit)Enum.Parse(typeof(MapUnit), mapUnitString);
203
}
204
Session["MeasureMapUnits"] = m_mapUnits;
205
//测量单位
206
string measureUnitString = queryString["MeasureUnits"];
207
if (measureUnitString != null && measureUnitString.Length > 0)
208
{
209
m_measureUnits = (MeasureUnit)Enum.Parse(typeof(MeasureUnit), measureUnitString);
210
}
211
//区域单位
212
string areaUnitstring = queryString["AreaUnits"];
213
if (areaUnitstring != null && areaUnitstring.Length > 0)
214
{
215
m_areaUnits = (AreaUnit)Enum.Parse(typeof(AreaUnit), areaUnitstring);
216
}
217
218
//输出内容字符串
219
string response = "";
220
PointCollection points = new PointCollection();
221
PointCollection dPoints = new PointCollection();
222
ArrayList distances = new ArrayList();
223
double totalDistance = 0;
224
double segmentDistance = 0;
225
double area = 0;
226
double perimeter = 0;
227
double roundFactor = Math.Pow(10, m_numberDecimals);
228
double xD, yD, tempDist, tempDist2, tempArea, x1, x2, y1, y2;
229
230
//动作为添加点
231
if (vectorAction == "addpoint")
232
{
233
//坐标点大于1个时,就是保证是一条线
234
if (coordPairs != null && coordPairs.Length > 1)
235
{
236
for (int i = 0; i < coordPairs.Length; i++)
237
{
238
xys = coordPairs[i].Split(char.Parse(":"));
239
//像素坐标转换成地理坐标
240
points.Add(Point.ToMapPoint(Convert.ToInt32(xys[0]), Convert.ToInt32(xys[1]), m_map.GetTransformationParams(ESRI.ArcGIS.ADF.Web.Geometry.TransformationDirection.ToMap)));
241
242
if (i > 0)//第二个坐标点的时候
243
{
244
if (m_mapUnits == MapUnit.Degrees)//地图单位为度的时候
245
{
246
//计算与前一个点的距离,分段距离
247
tempDist = DegreeToFeetDistance(points[i - 1].X, points[i - 1].Y, points[i].X, points[i].Y);
248
//度转成码
249
y1 = DegreeToFeetDistance(points[i].X, points[i].Y, points[i].X, 0);
250
//度转成码
251
x1 = DegreeToFeetDistance(points[i].X, points[i].Y, 0, points[i].Y);
252
dPoints.Add(new Point(x1, y1));
253
//单位换算
254
segmentDistance = ConvertUnits(tempDist, MapUnit.Feet, m_measureUnits);
255
}
256
else//地图单位为米的时候
257
{
258
xD = Math.Abs(points[i].X - points[i - 1].X);
259
yD = Math.Abs(points[i].Y - points[i - 1].Y);
260
//计算2个坐标之间的距离
261
tempDist = Math.Sqrt(Math.Pow(xD, 2) + Math.Pow(yD, 2));
262
//单位换算
263
segmentDistance = ConvertUnits(tempDist, m_mapUnits, m_measureUnits);
264
265
}
266
267
//把分段距离添加到distances
268
distances.Add(segmentDistance);
269
//计算总距离
270
totalDistance += segmentDistance;
271
//只显示4位小数
272
segmentDistance = Math.Round(segmentDistance * roundFactor) / roundFactor;
273
totalDistance = Math.Round(totalDistance * roundFactor) / roundFactor;
274
}
275
else//第一个坐标点的时候
276
{
277
if (m_mapUnits == MapUnit.Degrees)
278
{
279
//度转成码
280
y1 = DegreeToFeetDistance(points[i].X, points[i].Y, points[i].X, 0);
281
x1 = DegreeToFeetDistance(points[i].X, points[i].Y, 0, points[i].Y);
282
dPoints.Add(new Point(x1, y1));
283
}
284
}
285
}
286
}
287
288
//为多边形时
289
if (eventArg == "polygon")
290
{
291
if (points.Count > 2)
292
{
293
if (m_mapUnits == MapUnit.Degrees)
294
{
295
//最后一段的距离计算
296
tempDist = DegreeToFeetDistance(points[points.Count - 1].X, points[points.Count - 1].Y, points[0].X, points[0].Y);
297
tempDist2 = ConvertUnits(tempDist, MapUnit.Feet, m_measureUnits);
298
distances.Add(tempDist2);
299
//加入第一点作为多边形的结束节点
300
dPoints.Add(dPoints[0]);
301
}
302
else
303
{
304
//最后一段的距离计算
305
xD = Math.Abs(points[points.Count - 1].X - points[0].X);
306
yD = Math.Abs(points[points.Count - 1].Y - points[0].Y);
307
tempDist = Math.Sqrt(Math.Pow(xD, 2) + Math.Pow(yD, 2));
308
tempDist2 = ConvertUnits(tempDist, m_mapUnits, m_measureUnits);
309
distances.Add(tempDist2);
310
}
311
//加入第一点作为多边形的结束节点
312
points.Add(points[0]);
313
//总长度+最后一段长度
314
perimeter = totalDistance + tempDist2;
315
//多边形面积计算
316
tempArea = 0;
317
MapUnit mUnits = m_mapUnits;
318
for (int j = 0; j < points.Count - 1; j++)
319
{
320
if (m_mapUnits == MapUnit.Degrees)
321
{
322
x1 = Convert.ToDouble(dPoints[j].X);
323
x2 = Convert.ToDouble(dPoints[j + 1].X);
324
y1 = Convert.ToDouble(dPoints[j].Y);
325
y2 = Convert.ToDouble(dPoints[j + 1].Y);
326
mUnits = MapUnit.Feet;
327
}
328
else
329
{
330
x1 = Convert.ToDouble(points[j].X);
331
x2 = Convert.ToDouble(points[j + 1].X);
332
y1 = Convert.ToDouble(points[j].Y);
333
y2 = Convert.ToDouble(points[j + 1].Y);
334
}
335
//tempArea += tempArea + (x1 + x2) * (y1 - y2);
336
double xDiff = x2 - x1;
337
double yDiff = y2 - y1;
338
tempArea += x1 * yDiff - y1 * xDiff;
339
}
340
tempArea = Math.Abs(tempArea) / 2;
341
//单位换算
342
area = ConvertAreaUnits(tempArea, mUnits, m_areaUnits);
343
//保留4位小数
344
perimeter = Math.Round(perimeter * roundFactor) / roundFactor;
345
area = Math.Round(area * roundFactor) / roundFactor;
346
347
//输出显示内容html
348
response = String.Format("<table cellspacing='0' ><tr><td>Perimeter: </td><td align='right'>{0}</td><td>{1}</td></tr><tr><td>Area:</td><td align='right'>{2}</td><td>{3}</td></tr></table>", perimeter, WriteMeasureUnitDropdown(), area, WriteAreaUnitDropdown());
349
}
350
else
351
{
352
//输出显示内容html,小于3个点时候
353
response = String.Format("<table cellspacing='0' ><tr><td>Perimeter: </td><td align='right'> 0</td><td>{0}</td></tr><tr><td>Area:</td><td align='right'>0 </td><td>{1}</td></tr></table>", WriteMeasureUnitDropdown(), WriteAreaUnitDropdown());
354
}
355
}
356
else
357
{
358
//输出显示内容html,为线的时候
359
response = String.Format("<table cellspacing='0' ><tr><td>Segment: </td><td align='right'>{0} </td><td>{1}</td></tr><tr><td>Total Length:</td><td align='right'>{2} </td><td>{3}</td></tr></table>", segmentDistance, m_measureUnits.ToString(), totalDistance, WriteMeasureUnitDropdown());
360
}
361
362
}
363
//动作为获取坐标
364
else if (vectorAction == "coordinates")
365
{
366
xys = coordPairs[0].Split(char.Parse(":"));
367
Point coordPoint = Point.ToMapPoint(Convert.ToInt32(xys[0]), Convert.ToInt32(xys[1]), m_map.GetTransformationParams(ESRI.ArcGIS.ADF.Web.Geometry.TransformationDirection.ToMap));
368
369
//输出坐标的html显示内容
370
response = String.Format("<table cellspacing='0' ><tr><td>X Coordinate:</td><td align='right'>{0}</td></tr><tr><td>Y Coordinate:</td><td align='right'>{1}</td></tr></table>", (Math.Round(coordPoint.X * roundFactor) / roundFactor).ToString(), (Math.Round(coordPoint.Y * roundFactor) / roundFactor).ToString());
371
}
372
//动作为结束画线
373
else if (vectorAction == "finish")
374
{
375
response = "Shape complete";
376
}
377
378
//把结果内容返回给客户端
379
return String.Format("measure:::{0}:::{1}:::{2}", m_id, vectorAction, response);
380
}
381
382
//输出测量单位选择下拉框
383
public string WriteMeasureUnitDropdown()
384
{
385
System.Text.StringBuilder sb = new System.Text.StringBuilder();
386
sb.Append("<select id=\"MeasureUnits2\" onchange=\"changeMeasureUnits()\" style=\"font: normal 7pt Verdana; width: 100px;\">");
387
Array mArray = Enum.GetValues(typeof(MeasureUnit));
388
foreach (MeasureUnit mu in mArray)
389
{
390
sb.AppendFormat("<option value=\"{0}\" {1}>{0}</option>", mu.ToString(), CheckFormMeasureUnits(mu.ToString()));
391
392
}
393
sb.Append("</select>");
394
395
return sb.ToString();
396
}
397
398
//检查默认选中项
399
public string CheckFormMeasureUnits(string unit)
400
{
401
string response = "";
402
if (unit == m_measureUnits.ToString())
403
response = "selected=\"selected\"";
404
return response;
405
}
406
407
//输出测量单位选择下拉框
408
public string WriteAreaUnitDropdown()
409
{
410
System.Text.StringBuilder sb = new System.Text.StringBuilder();
411
sb.Append("<select id=\"AreaUnits2\" onchange=\"changeAreaUnits()\" style=\"font: normal 7pt Verdana; width: 100px;\">");
412
Array aArray = Enum.GetValues(typeof(AreaUnit));
413
foreach (AreaUnit au in aArray)
414
{
415
sb.AppendFormat("<option value=\"{0}\" {1}>{0}</option>", au.ToString(), CheckFormAreaUnits(au.ToString()));
416
417
}
418
sb.Append("</select>");
419
420
return sb.ToString();
421
}
422
423
//检查默认选中项
424
public string CheckFormAreaUnits(string unit)
425
{
426
string response = "";
427
if (unit == m_areaUnits.ToString())
428
response = "selected=\"selected\"";
429
return response;
430
}
431
432
//面积单位换算
433
private double ConvertAreaUnits(double area, MapUnit baseUnits, AreaUnit toUnits)
434
{
435
double mArea = area;
436
if (baseUnits == MapUnit.Feet)
437
{
438
if (toUnits == AreaUnit.Acres)
439
mArea = area * 0.000022956;
440
else if (toUnits == AreaUnit.Sq_Meters)
441
mArea = area * 0.09290304;
442
else if (toUnits == AreaUnit.Sq_Miles)
443
mArea = area * 0.00000003587;
444
else if (toUnits == AreaUnit.Sq_Kilometers)
445
mArea = area * 0.09290304 / 1000000;
446
}
447
else if (baseUnits == MapUnit.Meters)
448
{
449
if (toUnits == AreaUnit.Acres)
450
mArea = area * 0.0002471054;
451
else if (toUnits == AreaUnit.Sq_Miles)
452
mArea = area * 0.0000003861003;
453
else if (toUnits == AreaUnit.Sq_Kilometers)
454
mArea = area * 1.0e-6;
455
else if (toUnits == AreaUnit.Sq_Feet)
456
mArea = area * 10.76391042;
457
}
458
459
return mArea;
460
}
461
462
//单位换算
463
public double ConvertUnits(double distance, MapUnit fromUnits, MeasureUnit toUnits)
464
{
465
double mDistance = distance;
466
if (fromUnits == MapUnit.Feet)
467
{
468
if (toUnits == MeasureUnit.Miles)
469
{
470
mDistance = distance / 5280;
471
}
472
else if (toUnits == MeasureUnit.Meters)
473
{
474
mDistance = distance * 0.304800609601;
475
}
476
else if (toUnits == MeasureUnit.Kilometers)
477
{
478
mDistance = distance * 0.0003048;
479
}
480
}
481
else
482
{
483
if (toUnits == MeasureUnit.Miles)
484
{
485
mDistance = distance * 0.0006213700922;
486
}
487
else if (toUnits == MeasureUnit.Feet)
488
{
489
mDistance = distance * 3.280839895;
490
}
491
else if (toUnits == MeasureUnit.Kilometers)
492
{
493
mDistance = distance / 1000;
494
}
495
}
496
return mDistance;
497
}
498
499
//度转成码距离
500
private double DegreeToFeetDistance(double x1, double y1, double x2, double y2)
501
{
502
double Lat1 = DegToRad(y1);
503
double Lat2 = DegToRad(y2);
504
double Lon1 = DegToRad(x1);
505
double Lon2 = DegToRad(x2);
506
double LonDist = Lon1 - Lon2;
507
double LatDist = Lat1 - Lat2;
508
double x = Math.Pow(Math.Sin(LatDist / 2), 2) + Math.Cos(Lat1) * Math.Cos(Lat2) * Math.Pow(Math.Sin(LonDist / 2), 2);
509
x = 2 * Math.Asin(Math.Min(1, Math.Sqrt(x)));
510
x = (3963 - 13 * Math.Sin((Lat1 + Lat2) / 2)) * x;
511
// in miles
convert to feet and use that as base
512
return (x * 5280);
513
}
514
515
//度转成弧度
516
private double DegToRad(double degrees)
517
{
518
return Convert.ToDouble(degrees * Math.PI / 180);
519
}
520
521
private MapUnit GetResourceDefaultMapUnit()
522
{
523
MapUnit mUnit = MapUnit.Degrees;
524
try
525
{
526
//获取地图资源单位
527
Units mu = m_mapFunctionality.Units;
528
if (mu == Units.DecimalDegrees)
529
{
530
mUnit = MapUnit.Degrees;
531
}
532
else if (mu == Units.Feet)
533
{
534
mUnit = MapUnit.Feet;
535
}
536
else if (mu == Units.Meters)
537
{
538
mUnit = MapUnit.Meters;
539
}
540
541
}
542
catch
543
{
544
//不能获取地图资源单位时用m_FallbackMapUnit定义的单位
545
mUnit = m_FallbackMapUnit;
546
}
547
return mUnit;
548
549
}
550
551
public string Id
552
{
553
get { return m_id; }
554
set { m_id = value; }
555
}
556
557
private string ClientCallbackInvocation
558
{
559
get { return m_callbackInvocation; }
560
set { m_callbackInvocation = value; }
561
}
562
563
private MapResourceManager MapResourceManager
564
{
565
get { return m_resourceManger; }
566
set { m_resourceManger = value; }
567
}
568
569
/// <summary>
570
/// Id of Buddy MapControl
571
/// </summary>
572
public string MapBuddyId
573
{
574
get { return m_mapBuddyId; }
575
set { m_mapBuddyId = value; }
576
}
577
578
579
/// <summary>
580
/// Unit used resource. Resource_Default will return value from resource, if available. Other values will force calculations to use that unit.
581
/// </summary>
582
public MapUnit MapUnits
583
{
584
get { return m_startMapUnits; }
585
set { m_startMapUnits = value; }
586
}
587
588
/// <summary>
589
/// Unit used in display of linear measurements.
590
/// </summary>
591
public MeasureUnit MeasureUnits
592
{
593
get { return m_measureUnits; }
594
set { m_measureUnits = value; }
595
}
596
597
/// <summary>
598
/// Area Units - Unit used in display of area measurements.
599
/// </summary>
600
public AreaUnit AreaUnits
601
{
602
get { return m_areaUnits; }
603
set { m_areaUnits = value; }
604
}
605
606
// Number of Decimals - Number of decimal digits displayed in measurements.
607
public double NumberDecimals
608
{
609
get { return m_numberDecimals; }
610
set { m_numberDecimals = value; }
611
}
612
613
614
public override bool Visible
615
{
616
get { return base.Visible; }
617
}
618
619
public override bool EnableTheming
620
{
621
get
622
{
623
return base.EnableTheming;
624
}
625
}
626
627
public override bool EnableViewState
628
{
629
get
630
{
631
return base.EnableViewState;
632
}
633
}
634
635
}
636
}

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

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

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

377

378

379

380

381

382

383

384

385

386

387

388

389

390

391

392

393

394

395

396

397

398

399

400

401

402

403

404

405

406

407

408

409

410

411

412

413

414

415

416

417

418

419

420

421

422

423

424

425

426

427

428

429

430

431

432

433

434

435

436

437

438

439

440

441

442

443

444

445

446

447

448

449

450

451

452

453

454

455

456

457

458

459

460

461

462

463

464

465

466

467

468

469

470

471

472

473

474

475

476

477

478

479

480

481

482

483

484

485

486

487

488

489

490

491

492

493

494

495

496

497

498

499

500

501

502

503

504

505

506

507

508

509

510

511


512

513

514

515

516

517

518

519

520

521

522

523

524

525

526

527

528

529

530

531

532

533

534

535

536

537

538

539

540

541

542

543

544

545

546

547

548

549

550

551

552

553

554

555

556

557

558

559

560

561

562

563

564

565

566

567

568

569

570

571

572

573

574

575

576

577

578

579

580

581

582

583

584

585

586

587

588

589

590

591

592

593

594

595

596

597

598

599

600

601

602

603

604

605

606

607

608

609

610

611

612

613

614

615

616

617

618

619

620

621

622

623

624

625

626

627

628

629

630

631

632

633

634

635

636

3.代码贴太多了编辑器死掉了一样了,郁闷换个新篇继续写了...