ElasticsearchCRUD使用(十三)【Elasticsearch谷歌地图搜索的MVC应用】

elasticsearch中geo_shape查询踩坑记录 参考链接:https://github.com/elastic/elasticsearch/issues/32805 问题发现: 当我用下面的查询方法进行查询的时候,发现没有结果,但是index里面是有数据的 GET app_tzn_test_service_tzn_test3_kdm_ctserver/service_tzn_test3/_search { "query" : { ... 阅读详情

本文介绍如何创建一个使用谷歌地图和Elasticsearch的MVC应用程序进行geo_distance搜索,并找到最近的点(文档)到您的位置。
Elasticsearch索引使用geo_point来定义每个文档的位置。Elasticsearch支持GeoJson格式。

Elasticsearch索引和类型使用以下模型创建:

public class MapDetail
{
    public long Id { get; set; }

    public string Name { get; set; }

    public string Details { get; set; }

    public string Information { get; set; }

    public string DetailsType { get; set; }

    [ElasticsearchGeoPoint]
    public GeoPoint DetailsCoordinates { get; set; }
}

DetailsCoordinates属性使用GeoPoint类,用于geo_distance搜索。 Elasticsearch中的映射使用ElasticsearchCRUD的IndexCreate方法创建。 Elasticsearch中的Geo类型如果是geo_point,则需要一个ElasticsearchGeoPoint属性,如果它是一个shape 类型,则需要一个ElasticsearchGeoShape属性。 必须映射Geo属性,并在索引新文档时不能自动创建。

public void InitMapDetailMapping()
{
    using (var context = new ElasticsearchContext(
        ConnectionString, 
        new ElasticsearchSerializerConfiguration(_elasticsearchMappingResolver)))
    {
        context.TraceProvider = new ConsoleTraceProvider();
        context.IndexCreate<MapDetail>();
    }
}

可以使用以下方式查看映射:

http://localhost:9200/_mapping

这里写图片描述

一旦创建了索引和类型,就会使用_bulk API添加一些数据。 这些文件都使用SaveChanges()方法发送。

public void AddMapDetailData()
{
    var dotNetGroup = new MapDetail { DetailsCoordinates = new GeoPoint(7.47348, 46.95404), Id = 1, Name = ".NET User Group Bern", Details = "http://www.dnug-bern.ch/", DetailsType = "Work" };
    var dieci = new MapDetail { DetailsCoordinates = new GeoPoint(7.41148, 46.94450), Id = 2, Name = "Dieci Pizzakurier Bern", Details = "http://www.dieci.ch", DetailsType = "Pizza" };
    var babylonKoeniz = new MapDetail { DetailsCoordinates = new GeoPoint(7.41635, 46.92737), Id = 3, Name = "PIZZERIA BABYLON Köniz", Details = "http://www.pizza-babylon.ch/home-k.html", DetailsType = "Pizza" };
    var babylonOstermundigen = new MapDetail { DetailsCoordinates = new GeoPoint(7.48256, 46.95578), Id = 4, Name = "PIZZERIA BABYLON Ostermundigen", Details = "http://www.pizza-babylon.ch/home-o.html", DetailsType = "Pizza" };
    using (var context = new ElasticsearchContext(ConnectionString, new ElasticsearchSerializerConfiguration(_elasticsearchMappingResolver)))
    {
        context.TraceProvider = new ConsoleTraceProvider();
        context.AddUpdateDocument(dotNetGroup, dotNetGroup.Id);
        context.AddUpdateDocument(dieci, dieci.Id);
        context.AddUpdateDocument(babylonKoeniz, babylonKoeniz.Id);
        context.AddUpdateDocument(babylonOstermundigen, babylonOstermundigen.Id);
        context.SaveChanges();
    }
}

Elasticsearch中的索引和类型在global.asax Application_Start方法中初始化。 这将检查索引是否存在,并创建一个新的索引(如果没有)。

private void InitSearchEngine()
{
    var searchProvider = new SearchProvider();

    if (!searchProvider.MapDetailsIndexExists())
    {
        searchProvider.InitMapDetailMapping();
        searchProvider.AddMapDetailData();
    }
}

使用geo_distance filter 和 query查询索引。 这将搜索最大距离内的所有文档,并从最接近您的搜索位置的升序排序命中结果。

{
  "query" :
  {
    "filtered" : {
        "query" : {
            "match_all" : {}
        },
        "filter" : {
            "geo_distance" : {
                "distance" : "300m",
                 "detailscoordinates" : [7.41148,46.9445]
            }
        }
    }
  },
 "sort" : [
        {
            "_geo_distance" : {
                "detailscoordinates" : [7.41148,46.9445],
                "order" : "asc",
                "unit" : "m"
            }
        }
    ]
    }
}

上面的Elasticsearch 查询看起来像这样在C#

var search = new Search
{
    Query = new Query(
        new Filtered( 
            new Filter(
                new GeoDistanceFilter( 
                    "detailscoordinates", 
                    new GeoPoint(centerLongitude, centerLatitude), 
                    new DistanceUnitMeter(maxDistanceInMeter)
                )
            )
        )
        {
            Query = new Query(new MatchAllQuery())
        }
    ),
    Sort = new SortHolder(
        new List<ISort>
        {
            new SortGeoDistance("detailscoordinates", DistanceUnitEnum.m)
            {
                Order = OrderEnum.asc
            }
        }
    )
};

然后在HomeController中使用它,如下所示:

public ActionResult Search(int maxDistanceInMeter, double centerLongitude, double centerLatitude)
{
    var searchResult = _searchProvider.SearchForClosest(maxDistanceInMeter, centerLongitude, centerLatitude);
    var mapModel = new MapModel
    {
        MapData = new JavaScriptSerializer().Serialize(searchResult),
        CenterLongitude = centerLongitude,
        CenterLatitude = centerLatitude,
        MaxDistanceInMeter = maxDistanceInMeter
    };

    return View("Index", mapModel);
}   

razor 索引视图使用此数据在地图显示中。 使用绿色图像显示与您的搜索位置最接近的文档。 最大搜索距离内的所有命中也显示在地图中。 您可以移动您的中心位置,增加或减少最大允许距离,结果将被正确显示。

@*Bern  Lat 46.94792, Long 7.44461 *@
@model WebAppGeoElasticsearch.Models.MapModel

<input type="hidden" value="@Model.MapData" id="mapdata" name="mapdata" />

@using (Html.BeginForm("Search", "Home"))
{
    <fieldset class="form">
        <legend>SEARCH for closest document in the search engine using geo distance</legend>
        <table width="800">
            <tr>
                <th></th>
            </tr>
            <tr>

            </tr>
            <tr>
                <td>
                    <input type="submit" value="Search fo closest: " style="width: 300px">
                </td>
                <td>
                    <input type="hidden" value="@Model.CenterLongitude" id="centerLongitude" name="centerLongitude" />
                    <input type="hidden" value="@Model.CenterLatitude" id="centerLatitude" name="centerLatitude" />

                </td>
                <td>
                    <p style="width: 300px">Max distance in meter:</p>
                    <input id="maxDistanceInMeter" name="maxDistanceInMeter" type="text" title="" value="@Model.MaxDistanceInMeter" style="width: 200px" />
                </td>
            </tr>
        </table>
    </fieldset>

}

<div class="row">
    @*Bern  Lat 46.94792, Long 7.44461 *@
    <div id="googleMap" style="width: 1000px; height: 800px;">
    </div>
</div>

@section scripts
{
    <script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
    <script type="text/javascript" src="http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markermanager/src/markermanager.js"></script>

    <script language="javascript" type="text/javascript">
        var map;
        var mgr;

        function initialize() {
            var myOptions = {
                zoom: 13,
                center: new google.maps.LatLng(46.94792, 7.44461),
                mapTypeId: google.maps.MapTypeId.ROADMAP
            };
            map = new google.maps.Map(document.getElementById("googleMap"), myOptions);
            mgr = new MarkerManager(map);
            var infoWindow = new google.maps.InfoWindow({ content: "contents" });
            google.maps.event.addListener(mgr, 'loaded', function() {

                var modelData = $.parseJSON($("#mapdata").val());

                var first = true;
                $.each(modelData, function(entryIndex, entry) {
                    //alert("Data" + entry.DetailsCoordinates + ", " + entry.Details);

                    var htmlString = "<a href=\"" + entry.Details + "\">" + entry.Name + "</a>";
                    var coor = entry.DetailsCoordinates.toString();
                    var array = coor.split(',');

                   // alert("Lat" + array[1] + "Long" + array[0]);
                    if (first) {
                        var marker = new google.maps.Marker({
                            position: new google.maps.LatLng(array[1], array[0]),
                            html: htmlString,
                            icon: "http://localhost:2765/Content/yourposition.png"
                        });

                        first = false;
                    } else {
                        var marker = new google.maps.Marker({
                            position: new google.maps.LatLng(array[1], array[0]),
                            html: htmlString
                        });
                    }

                    google.maps.event.addListener(marker, "click", function() {
                        infoWindow.setContent(this.html);
                        infoWindow.open(map, this);
                    });

                    mgr.addMarker(marker, 0);

                });

               // alert('homemarker: ' + $("#centerLatitude").val() + ' Current Lng: ' + $("#centerLongitude").val());

                var homemarker = new google.maps.Marker({

                    position: new google.maps.LatLng($("#centerLatitude").val(), $("#centerLongitude").val()),
                    html: "YOU",
                    draggable: true,
                    icon: "http://localhost:2765/Content/ort.png"
                });

                google.maps.event.addListener(homemarker, 'dragend', function(evt) {
                   // alert('Marker dropped: Current Lat: ' + evt.latLng.lat().toFixed(3) + ' Current Lng: ' + evt.latLng.lng().toFixed(3));
                    $("#centerLongitude").val(evt.latLng.lng().toFixed(3));
                    $("#centerLatitude").val(evt.latLng.lat().toFixed(3));
                });

                mgr.addMarker(homemarker, 0);

                mgr.refresh();
            });
        }

        google.maps.event.addDomListener(window, 'load', initialize);
    </script>
}

搜索后的应用程序视图:
这里写图片描述

结论

您可以看到,使用Elasticsearch进行Geo搜索很容易。 支持一系列Geo搜索过滤器,地理边界框过滤器,地理距离过滤器,地理距离范围过滤器,地理多边形过滤器,GeoShape过滤器,Geohash信元过滤器(Geo Bounding Box Filter, Geo Distance Filter, Geo Distance Range Filter, Geo Polygon Filter, GeoShape Filter, Geohash Cell Filter)以及大多数geoJSON形状和GeoShape查询。 可以创建最优搜索以匹配大多数要求。

SAP-PM设备模块-PM主数据之功能位置 SAP-PM模块学习 阅读详情

相关推荐

价值投资/指标选股(akshare)

利用akshare的数据源,可以获取所有的股票数据以及公开的财务数据,可以进行条件筛选,获取满足条件的股票。 这套模板可以用于价值投资,指标选股。选股周期为日线级别。然后结果可以邮箱发送。 import time import akshare as ak ## A 股上市公司的实时行情数据 stock_zh_a_spot_df = ak.stock_zh_a_spot() #print(stock_zh_a_spot_df) ##取前300测试 ##取前300测试 df_stock =...

qq_26742269的博客 1万+

Elasticsearch:如何制作 GeoJSON 文件并进行地理位置搜索

我发现我之前的文章 “Elasticsearch:使用 Elasticsearch 进行地理位置搜索” 还是蛮手欢迎的。我觉得大家喜欢是因为里面还有一些图片把复制的问题简单化,一目了然。在使用 Geo search 进行讲解时,如果能在地图上清楚地展示各个文档,边界,那么一切问题就变得非常简单了。在今天的文章中,我来讲述如何使用 GeoJSON 来创建一些边界。这对于展示一些搜索非常有用。 GeoJSON 文件格式 我们首先来看一下一个简单的 GeoJSON 文件格式: sample.json .

Elastic 中国社区官方博客 3972

ADS新手必看:用Filter DesignGuide快速搞定一个4GHz LC低通滤波器(附保姆级避坑指南)

本文为ADS新手提供了4GHz LC低通滤波器的完整设计流程,重点介绍了如何使用Filter DesignGuide避免参数设置陷阱、正确解读仿真结果以及解决实际电路与理论值的偏差问题。通过真实工程案例,详细讲解了工程创建、Filter DesignGuide配置、电路优化、仿真设置及实际工程中的进阶技巧,帮助工程师快速掌握LC滤波器设计。

weixin_30878501的博客 300

elasticsearch批量导入json数据

方法1:使用 postman 导入 json 数据集的内容以行作为分割,不要添加除换行以外的空格 每两行作为一条文档,第一行的 _index 指明索引,_id 指明该条文档的id;第二行为具体的数据内容; { "index" : { "_index" : "material", "_id": 1} } {"name_ch": "阿贝数","name_en": "Abbe number","explain": "即倒色散系数见平均色散。"} 假设写入 es 数据库的 material 索引中; 使

SevenBerry的博客 6328

Lumerical FDTD新手必看:从零开始搭建光子晶体仿真环境(附完整脚本)

本文为Lumerical FDTD新手提供光子晶体仿真环境的完整搭建指南,涵盖从基础参数设置到脚本编写的全流程。通过典型光子晶体带隙分析案例,详细讲解结构建模、仿真参数配置及后处理技巧,并附赠完整MATLAB脚本,帮助用户快速掌握FDTD仿真核心技术。

3c4x5z6v7b的博客 1050

MOSFET热失效机理与保护电路设计:实战案例

深入解析MOSFET工作原理及其在高温下的失效机制,结合实际案例探讨有效保护电路设计,提升系统可靠性与安全性。

weixin_28713083的博客 850

Kibana:摄入 GeoJSON 数据

GeoJSON 是一种用于编码各种地理数据结构的格式。GeoJSON 支持以下几何类型:Point、LineString、Polygon、MultiPoint、MultiLineString 和 MultiPolygon。具有附加属性的几何对象是特征对象。特征集包含在 FeatureCollection 对象中。GeoJSON 可以用于 Elastic Maps 应用中。在本教程中,你将构建一个自定义地图,显示两个机场之间的飞行路径,以及该路线上的闪电热点。

Elastic 中国社区官方博客 1187

3D Slicer-最强大的开源医学图像分割工具简要概述

3D Slicer 是一个免费的开源软件平台,用于医学、生物医学和其他 3D 图像的可视化、处理、分割、配准和分析。读/写DICOM图像和多种其他格式;三维图像、多边形网格和体积渲染的交互式可视化;手动编辑和标记图像;使用刚性和非刚性算法融合和共同配准数据;图像自动分割;跟踪图像引导程序的设备。所有的功能模块可在工具栏里找到,提供搜索,下拉选择,左右切换等功能。3D slicer的大概情况就介绍到这里。它的功能非常强大,也没有必要说掌握每个功能的使用。

Tina姐的博客 2万+

ElasticSearch学习并使用

本文以能在项目中应用为目的,介绍es的基本知识、注意点和基本操作。

用针戳左手中指指头的博客 6471

ArcMap|时空地理加权回归(GTWR)

ArcGIS的GTWR插件下载地址:https://www.researchgate.net/publication/329518786_GTWR_ADDIN_Valid_till_Dec_31_2022 更详细的操作参考: https://www.bilibili.com/video/BV1fR4y1M7xB?spm_id_from=333.999.0.0 https://blog.youkuaiyun.com/weixin_40008135/article/details/112693520 双击“GTWR_Be

个人学习笔记 1万+

爆肝5万字❤️Open3D 点云数据处理基础(Python版)

本文为Open3D 点云数据处理基础教程(Python版),小白也能轻松上手!还等什么呢,学起来!

孙悟空 13万+

Elasticsearch地理位置

介绍 地理坐标点(geo-point) 是指地球表面可以用经纬度描述的一个点。地理坐标点可以用来计算两个坐标位置间的距离,或者判断一个点是否在一个区域中。地理坐标点不能被动态映射(dynamic mapping)自动检测,而是需要显式声明对应字段类型为 geo_point 。 PUT /attractions { "mappings": { "restaurant": { ...

qq_40907977的博客 925

如何使用 Python 爬虫获取猫眼电影数据:电影评分与评论分析

随着互联网的快速发展,越来越多的人开始使用各种在线平台来了解电影信息,猫眼电影作为一个非常流行的在线电影票务平台,提供了详细的电影评分、评论和票房数据。本篇博客将详细介绍如何使用 Python 爬虫技术获取猫眼电影平台上的电影数据,重点关注电影评分和用户评论的爬取,分析其背后的数据处理和反爬虫技术。如果你对数据分析、电影评论分析等话题感兴趣,可以根据本文的示例进一步深入挖掘更多的数据,为决策提供支持,或为电影产业的相关研究提供有价值的分析依据。有些猫眼电影的页面数据是动态加载的,使用。

2201_76125261的博客 1621

Elasticsearch地理位置数据索引

geo_point和geo_shape。这些字段类型允许 Elasticsearch 存储和查询地理空间数据,如坐标点、线和多边形。

www_tlj的专栏 2120

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

elasticsearch-head 谷歌插件以及安装和使用说明

文章目录1. 下载2. 扩展程序3. 打开开发者模式4. 拖动插件5. 添加扩展程序6. 点击es插件7. 连接8.效果对比 1. 下载 https://github.com/mobz/elasticsearch-head/tree/master/crx wget https://raw.githubusercontent.com/mobz/elasticsearch-head/master/crx/es-head.crx 2. 扩展程序 演示:谷歌浏览器 3. 打开开发者模式 4. 拖动插件 .

Gblfy_Blog 2593

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Python Elasticsearch Client 使用Bulk API把geojson数据导入es

geojson数据格式有GDAL通过ogr2ogr工具转换而来 geojson格式并不满足es bulk api对json的格式要求:BULK API 下面用py_es client来解析geojson,并使用bulk api导入es py_es client :https://elasticsearch-py.readthedocs.io/en/7.6.0/ 导入速度大概是:1500条/秒 # aganliang 20200519 # 使用ES python api插入geojson点...

aganliang的专栏 1038

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Google Chrome谷歌浏览器安装最新版Elasticsearch插件 图文教程 【一看就懂】

我们在虚拟机安装了Elasticsearch后,往往还需要再安装一个可视化界面以便于使用。本文就教您如何在Google Chrome谷歌浏览器安装最新版Elasticsearch(es)插件。 | 1 如图所示,点击设置 进入如下界面,点击扩展程序 开启开发者模式后点击Chrome网上应用商店 如图所示搜索插件ElasticSearch,并点击进入 进入插件主页后点击添加至Chrome 如图所示:点击添加扩展程序 添加成功后如图所示: 进入已安装好的Elast.

杨大仙 9103

Elasticsearch:使用 Point 和 Shape 字段类型

地理处理 Elasticsearch 的强大功能用于为大量应用程序提供功能。 但是,它有一个限制:它仅适用于世界坐标。使用 Point 和 Shape 类型,X-Pack 将地理功能扩展到每个二维平面坐标系。此用例的常见场景包括映射和记录建筑物坐标以及检查文档是否在形状内。...

Elastic 中国社区官方博客 1619

elasticsearch 深入 —— 地理位置

地理位置 我们拿着纸质地图漫步城市的日子一去不返了。得益于智能手机,我们现在总是可以知道 自己所处的准确位置,也预料到网站会使用这些信息。我想知道从当前位置步行 5 分钟内可到的那些餐馆,对伦敦更大范围内的其他餐馆并不感兴趣。 但地理位置功能仅仅是 Elasticsearch 的冰山一角,Elasticsearch 的妙处在于,它让你可以把地理位置、全文搜索、结构化搜索和分析结合到一起。 例...

gmHappy 7267

es教程——地图搜索

geo原理 geohashes geohashes值实际上是代表一个区域。 geohashes 是一种将经纬度编码成字符串的方式。   以经纬度值(116.389550, 39.928167)为例。   (1)首先对纬度进行编码, 纬度范围是[-90, 90],首先将该范围进行划分[-90, 0], [0, 90],然后可以确定 39.9 属于后一部分,所以标记为 1, 然后在对[0, 90]进行划分[0, 45], [45, 90] 可知39.9属于前一部分,所以标记为0, 此时纬度区间越来越接近39.9

HJHxHJH的博客 2051

Elasticsearch:使用 Node.js 将实时数据提取到 Elasticsearch 中(一)

​ Elasticsearch 是一个强大的 RESTful 搜索和分析引擎,能够处理越来越多的用例。 它将集中存储你的数据,以实现闪电般的快速搜索、微调相关性以及可轻松扩展的强大分析。 关于如何使用 Elastic Stack(又名 ELK 堆栈)将数据摄取到 Elasticsearch 的资源有很多。在今天的文章中,我将详细介绍如何使用 Node.js 从零开始来把地震的实时数据采集到 Elasticsearch 中。

Elastic 中国社区官方博客 2234

【ElasticSearch】ES Java API 实现地理位置搜索

ElasticSearch 实现 geo_point 和 geo_shape 两种类型的地理位置搜索,附带 Java API 代码

weixin_48500080的博客 1404

Elasticsearch权威指南:GeoJSON地理形状索引详解

Elasticsearch权威指南:GeoJSON地理形状索引详解 地理形状索引基础 在Elasticsearch中,地理形状(Geo Shapes)是一种强大的空间数据类型,它允许我们存储和查询复杂的二维地理图形。这些形状使用GeoJSON格式进行表示,这是一个简单开放的JSON标准,专门用于编码二维地理形状。 GeoJSON核心概念 GeoJSON中的每个形状定义都包含两个关键部分: 形状类...

gitblog_00941的博客 405

利用Elasticsearch实现地理位置、城市搜索服务

最近用到一些简单的地理位置查询接口,基于当前定位获取用户所在位置信息(省市区),然后基于该信息查询当前区域的......提供服务。 然后就自己研究了下GIS,作为一个程序员。自己能不能实现这个功能呢?答案当然是可以。立即开干。 思路:找到数据,写入数据库,利用Elasticsearch强大的搜索能力和丰富的GIS数据处理能力实现。 GIS相关专业信息参考(bd上找的,还算专业):程序员GIS入门...

weixin_37014889的博客 394

Elasticsearch笔记(九):实践篇-查找附近的人

到这里Elasticsearch的整个系列分享就基本上结束了,当然后续还是会针对某一点进行讲解。为何要在实践篇中讲解"查找附近的人"呢?说实话,想了很久,最终才确定下来,总体希望这个实践对今后的工作过程中有帮助。 1. 需求描述 随着移动设备的普及,很多移动APP都提供了LBS(Location Based Service)。其实LBS并不是什么新东西,但它也带来了不一样的改变,一方面可以提高...

布道 7945

在Elasticsearch7.4中创建Shape数据类型

在Elasticsearch7.4中,Shape数据类型(shape datatype)是可以用来索引和查询任意笛卡尔坐标系(x,y标识的直角坐标系)下的图形如矩形、多边形等。shape数据类型可以用来索引和检索位于一个二维平面坐标系统中的几何图形。 我们也可以基于shape数据类型使用shape query来检索文档。 在使用shape query来检索几何图形之前,必须对geometry类型的...

wjzt7322的博客 992
上一篇: ElasticsearchCRUD使用(十二)【Elasticsearch的German分析器】
下一篇: ElasticsearchCRUD使用(十四)【ElasticsearchCRUD搜索查询和过滤】
.NET跨平台
博客等级 码龄15年 6066粉丝 738原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值