• windows桌面程序集成webbrowser控件实现与高德地图的互操作


    运行效果如下:在桌面程序中访问高德地图,通过cs代码调用高德js接口实现多边形区域动态添加;通过鼠标点击事件实现当前位置经纬度采集并传递给cs代码,判断点击位置是否在指定的区域内。

    项目结构如下:

    核心代码如下:

    窗口代码:

    using System;
    using System.Collections.Generic;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    using System.Web.Script.Serialization;


    //----------------------------------------------------------------------
    //demo:集成webbrowser空间,实现windows桌面程序访问高德地图,
    // 基于高德地图的一些简单操作(地图上添加多边形区域、点击获取坐标等)
    //
    // 1、测试cs程序与html的互操作(cs调用js方法、js调用cs方法)
    // 2、测试指定点是否在指定的多边形区域内
    //
    //----------------------------------------------------------------------

    namespace testPointInPolygon
    {
    [ComVisibleAttribute(true)]//允许cs代码与js代码的互操作
    public partial class Form1 : Form
    {
    private PointInPolygon pip;
    public Form1()
    {
    InitializeComponent();
    }

    /// <summary>
    /// 公有方法,供js调用
    /// </summary>
    /// <param name="strPos"></param>
    public void GetMapPos(string strPos)
    {
    string[] pos = strPos.Split(',');
    this.txtPointX.Text = pos[0];
    this.txtPointY.Text = pos[1];
    }

    private void button2_Click(object sender, EventArgs e)
    {
    if (pip is null)
    {
    MessageBox.Show("请先添加区域。");
    return;
    }

    bool bFlag = pip.IsPointInPolygon(double.Parse(this.txtPointX.Text), double.Parse(this.txtPointY.Text));
    if (bFlag)
    {
    MessageBox.Show("指定点在区域内。");
    }
    else
    {
    MessageBox.Show("指定点不在区域内。");
    }
    }

    //构建多边形测试数据
    private List<PointXY> BuildPointList()
    {
    List<PointXY> listPoint = new List<PointXY>();
    PointXY point;

    point = new PointXY();
    point.PointX = 116.27582;
    point.PointY = 39.968792;
    listPoint.Add(point);

    point = new PointXY();
    point.PointX = 116.27479;
    point.PointY = 39.884015;
    listPoint.Add(point);

    point = new PointXY();
    point.PointX = 116.29024;
    point.PointY = 39.831305;
    listPoint.Add(point);

    point = new PointXY();
    point.PointX = 116.465334;
    point.PointY = 39.833151;
    listPoint.Add(point);

    point = new PointXY();
    point.PointX = 116.486277;
    point.PointY = 39.846859;
    listPoint.Add(point);

    point = new PointXY();
    point.PointX = 116.48971;
    point.PointY = 39.955108;
    listPoint.Add(point);

    point = new PointXY();
    point.PointX = 116.443705;
    point.PointY = 39.988523;
    listPoint.Add(point);

    point = new PointXY();
    point.PointX = 116.294016;
    point.PointY = 39.983788;
    listPoint.Add(point);

    return listPoint;
    }

    private void Form1_Load(object sender, EventArgs e)
    {
    // 防止 WebBrowser 控件打开拖放到其上的文件。
    webBrowser1.AllowWebBrowserDrop = false;
    // 防止 WebBrowser 控件在用户右击它时显示其快捷菜单.
    webBrowser1.IsWebBrowserContextMenuEnabled = false;
    // 以防止 WebBrowser 控件响应快捷键。
    webBrowser1.WebBrowserShortcutsEnabled = false;
    // 以防止 WebBrowser 控件显示脚本代码问题的错误信息。
    webBrowser1.ScriptErrorsSuppressed = true;
    // 这个属性比较重要,可以通过这个属性,把后台代码中的数据,传递到JS中,供内嵌的网页使用
    webBrowser1.ObjectForScripting = this;

    //打开本地指定html
    webBrowser1.Navigate(Application.StartupPath + "\html\OprMap.html");
    }

    private void button3_Click(object sender, EventArgs e)
    {

    List<PointXY> list = this.BuildPointList();
    pip = new PointInPolygon(list);

    List<object> lo = new List<object>();

    for (int i = 0; i < list.Count; i++)
    {
    object o = "[" + list[i].PointX + "," + list[i].PointY + "]";
    lo.Add(o);
    }

    JavaScriptSerializer jss = new JavaScriptSerializer();
    string strPos = jss.Serialize(lo).Replace('"',' ');
    //string strPos = "[[116.403322, 39.920255],[116.410703, 39.897555],[116.402292, 39.892353],[116.389846, 39.891365]]";

    //调用js中的方法
    webBrowser1.Document.InvokeScript("DrawPolygon", new object[] { strPos });
    }
    }


    }

    html代码:

     js代码:

     指定点是否在指定区域内:

    using System;
    using System.Collections.Generic;
    using System.Linq;


    namespace testPointInPolygon
    {
    public class PointInPolygon
    {
    private List<double> _PolygonX, _PolygonY;//指定多边形的点的X坐标集合、Y坐标集合
    private double _MaxX, _MinX, _MaxY, _MinY;//指定多边形的点的最大X坐标、最小X坐标、最大Y坐标、最小Y坐标
    private int _PolygonPointNumber;//多边形区域的点数

    /// <summary>
    /// 初始化区域的点坐标集合
    /// </summary>
    /// <param name="points">组成区域的点坐标集合</param>
    public PointInPolygon(List<PointXY> PolygonPoints)
    {
    _PolygonX = new List<double>();
    _PolygonY = new List<double>();
    for (int i = 0; i < PolygonPoints.Count; i++)
    {
    _PolygonX.Add(PolygonPoints[i].PointX);
    _PolygonY.Add(PolygonPoints[i].PointY);
    }

    _PolygonPointNumber = PolygonPoints.Count;
    PolygonPoints = PolygonPoints.OrderBy(ss => (ss.PointX)).ToList();
    _MinX = PolygonPoints.First().PointX;
    _MaxX = PolygonPoints.Last().PointX;
    PolygonPoints = PolygonPoints.OrderBy(ss => (ss.PointY)).ToList();
    _MinY = PolygonPoints.First().PointY;
    _MaxY = PolygonPoints.Last().PointY;
    }

    /// <summary>
    /// 指定的点是否在区域内
    /// </summary>
    /// <param name="PointX">指定点X坐标</param>
    /// <param name="PointY">指定点Y坐标</param>
    /// <returns></returns>
    public bool IsPointInPolygon(double PointX, double PointY)
    {
    //如果x、y坐标超出区域的最小最大坐标,直接返回false
    if (PointX < _MinX || PointX > _MaxX || PointY < _MinY || PointY > _MaxY)
    return false;

    int i, j, count = 0;
    for (i = 0, j = _PolygonPointNumber - 1; i < _PolygonPointNumber; j = i++)
    {
    if (((_PolygonY[i] > PointY) != (_PolygonY[j] > PointY)) &&
    (PointX < (_PolygonX[j] - _PolygonX[i]) * (PointY - _PolygonY[i]) / (_PolygonY[j] - _PolygonY[i]) + _PolygonX[i]))
    {
    count++;
    }
    }

    if (count % 2 == 1)
    {
    //单数在区域内
    return true;
    }
    else
    {
    //双数在区域外
    return false;
    }
    }
    }

    [Serializable]
    public class PointXY
    {
    public double PointX;
    public double PointY;
    }
    }

  • 相关阅读:
    第三周作业
    面向过程(或者叫结构化)分析方法与面向对象分析方法到底区别在哪里?请根据自己的理解简明扼要的回答。
    移动APP开发使用什么样的原型设计工具比较合适?
    java 从上至下打印二叉树
    Qt applendPlainText()/append() 多添加一个换行解决方法
    tolua 转换 std::shared_ptr
    cmake add_custom_command 使用
    Boost使用笔记(Smart_ptr)
    webpack4 安装
    git安装管理
  • 原文地址:https://www.cnblogs.com/coldlight/p/14713520.html
Copyright © 2020-2023  润新知