【问题标题】:Get Position from modal Google map in Razor view在 Razor 视图中从模态谷歌地图获取位置
【发布时间】:2019-02-07 16:17:26
【问题描述】:

我正在编写一个 MVC 项目,其中包括在 Google 地图中添加点的可能性。到目前为止,我可以通过硬编码纬度和经度值向 db 添加点,但我想让用户选择地图上的位置并将它们从 Razor 视图发送回控制器。 我已经编写了部分视图,并且可以打开带有地图和硬编码位置的模式弹出窗口。 我想做的是: 1.让用户在文本框中插入地址 2.打开模式弹出窗口,并在地址附近用标记将地图居中 3. 保存视图的两个字段中的位置,以便将它们发送回控制器。

我一直在使用 Google Developers 提供的代码: https://developers.google.com/maps/documentation/javascript/examples/place-details 并得出以下代码:

所有代码都在 Razor 视图中:

    <form>
        <fieldset>
            <legend>Ubicazione: </legend>


            <div class="form-group">
                @Html.LabelFor(model => model.Indirizzo, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    <button type="button" class="btn btn-default" style="float:left"
                            data-toggle="modal" data-target="#findInModal" data-backdrop="static"
                            data-keyboard="true" data-address='pippo'>
                        Trova posizione
                    </button>
                    @Html.EditorFor(model => model.Indirizzo, new { htmlAttributes = new { @class = "form-control" }, @id="addr" })
                    @Html.ValidationMessageFor(model => model.Indirizzo, "", new { @class = "text-danger" })
                </div>
            </div>


            <div class="form-group">
                @Html.LabelFor(model => model.Latitudine, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @*@Html.EditorFor(model => model.Latitudine, new { htmlAttributes = new { @class = "form-control" } })*@
                    @Html.DisplayFor(model => model.Latitudine, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.HiddenFor(model => model.Latitudine)
                    @Html.ValidationMessageFor(model => model.Latitudine, "", new { @class = "text-danger" })
                </div>
            </div>

            <div class="form-group">
                @Html.LabelFor(model => model.Longitudine, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @*@Html.EditorFor(model => model.Longitudine, new { htmlAttributes = new { @class = "form-control" } })*@
                    @Html.DisplayFor(model => model.Longitudine, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.HiddenFor(model => model.Longitudine)
                    @Html.ValidationMessageFor(model => model.Longitudine, "", new { @class = "text-danger" })
                </div>
            </div>
        </fieldset>
    </form>

我希望 data-address='pippo' 的值是 "@Html.EditorFor(model => model.Indirizzo ...." 中的地址。强>

这是打开地图并将其居中到硬编码位置的模式弹出内容:

    <!-- Find Location In Modal -->
    @using (Html.BeginForm())
    {
        @Html.AntiForgeryToken()


        <div class="modal fade" id="findInModal" tabindex="-1" role="dialog">
            <div class="modal-dialog" role="document">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title" style="height: 0px;"></h5>
                        <button type="button" class="close" data-dismiss="modal" aria-label="Chiudi">
                            <span aria-hidden="true">&times;</span>
                        </button>
                    </div>
                    <div class="modal-body">


                        <div id="gMap" style="height:400px;width:100%;"></div>
                        <script src="https://maps.googleapis.com/maps/api/js?key=APIKEY&language=it&region=IT&libraries=places&callback=gMap" async defer></script>
                        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
                        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
                        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
                        <script>

                            let myCenter;
                            let mapProp;
                            let map;
                            let service;

                            function gMap() {
                                myCenter = new google.maps.LatLng(41.893140, 12.483330);
                                mapProp = { center: myCenter, zoom: 15, scrollwheel: true, draggable: true, mapTypeId: google.maps.MapTypeId.HYBRID };
                                map = new google.maps.Map(document.getElementById("gMap"), mapProp);




                                let request = {
                                    query: 'Musei Capitolini',
                                    fields: ['name', 'geometry'],
                                };

                                service = new google.maps.places.PlacesService(map);

                                service.findPlaceFromQuery(request, function (results, status) {
                                    if (status === google.maps.places.PlacesServiceStatus.OK) {
                                        for (let i = 0; i < results.length; i++) {
                                            createMarker(results[i]);
                                        }

                                        map.setCenter(results[0].geometry.location);
                                    }
                                });
                            }
                            function createMarker(place) {
                                let marker = new google.maps.Marker({
                                    map: map,
                                    position: place.geometry.location,
                                    icon: "/Content/icons/01.png"
                                });
                                google.maps.event.addListener(marker, 'click', function () {
                                    infowindow.setContent(place.name + place.geometry.location);
                                    infowindow.open(map, this);
                                });
                            }
                        </script>

                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-secondary" data-dismiss="modal">Chiudi</button>
                        <button type="button" class="btn btn-primary">Salva</button>
                    </div>
                </div>
            </div>
        </div>
    }

这是打开弹出窗口的脚本:

    <script>

        $('#findInModal').on('show.bs.modal', function (event) {
            let button = $(event.relatedTarget) // Button that triggered the modal
            let AddressToFind = button.data('address') // Extract info from data-* attributes
            // If necessary, you could initiate an AJAX request here (and then do the updating in a callback).
            // Update the modal's content. We'll use jQuery here, but you could use a data binding library or other methods instead.
            let modal = $(this)
            modal.find('.modal-title').text('Find near: ' + AddressToFind)


        })

    </script>

目前我还没有实现如何将 place.geometry.location 值返回到父视图,但他们应该更新 model => model.Latitudinemodel => model.Longitudine 值将返回给控制器以更新数据库。

提前感谢您的帮助。

【问题讨论】:

    标签: javascript asp.net razor bootstrap-modal


    【解决方案1】:

    没有得到开发者的帮助,但是深入到 Google Developers 文档并在 JSFiddle 进行了测试,我最终得出了以下解决方案:

    @model GoogleMapTest.Models.MapPoint
    
    @{
        ViewBag.Title = "Create";
    }
    
    <h2>Create</h2>
    
    @using (Html.BeginForm())
    {
        @Html.AntiForgeryToken()
        @Html.ValidationSummary(true)
    
        <fieldset>
            <legend>MapPoint</legend>
    
            <div class="form-group">
                <div class="editor-label">
                    @Html.LabelFor(model => model.Address)
                </div>
                <div class="editor-field">
                    @Html.DisplayFor(model => model.Address)
                    @Html.HiddenFor(model => model.Address, new { id = "Address" })
                    @Html.ValidationMessageFor(model => model.Address)
                </div>
    
                <button type="button" class="btn btn-default" style="float: left"
                    data-toggle="modal" data-target="#findInModal" data-backdrop="static"
                    data-keyboard="true">
                    Find Position
                </button>
    
            </div>
    
    
            <div class="editor-label">
                @Html.LabelFor(model => model.Latitude)
            </div>
            <div class="editor-field">
                @Html.DisplayFor(model => model.Latitude)
                @Html.HiddenFor(model => model.Latitude, new { id = "Latitude" })
                @Html.ValidationMessageFor(model => model.Latitude)
            </div>
    
            <div class="editor-label">
                @Html.LabelFor(model => model.Longitude)
            </div>
            <div class="editor-field">
                @Html.DisplayFor(model => model.Longitude)
                @Html.HiddenFor(model => model.Longitude, new { id = "Longitude" })
                @Html.ValidationMessageFor(model => model.Longitude)
            </div>
    
            <p>
                <input type="submit" value="Create" />
            </p>
        </fieldset>
    }
    
    <div>
        @Html.ActionLink("Back to List", "Index")
    </div>
    
    @section Scripts {
        @Scripts.Render("~/bundles/jqueryval")
    }
    
    
    <!-- Find Location In Modal -->
    @using (Html.BeginForm())
    {
        @Html.AntiForgeryToken()
    
    
        <div class="modal fade" id="findInModal" tabindex="-1" role="dialog">
            <div class="modal-dialog" role="document">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title" style="height: 0px;">Set Point in Map</h5>
    
    
    
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                            <span aria-hidden="true">&times;</span>
                        </button>
                    </div>
                    <div class="modal-body">
                        <input id="pac-input" class="controls" type="text" placeholder="Find...">
    
                        <div id="gMap" style="height:400px;width:100%;"></div>
                        <script src="https://maps.google.com/maps/api/js?sensor=false&key=AIzaSyDMD8_QumYpomzDTcHW-myppqsyCZRsnB8"
                                    // APIkey end with call to libraries "&libraries=places&callback=initAutocomplete"
                                async defer></script>
    
                        <script>
    
    
                            function initAutocomplete() {
                                var map = new google.maps.Map(document.getElementById('gMap'), {
                                    center: { lat: 41.893321, lng: 12.482929 },
                                    zoom: 13,
                                    mapTypeId: 'hybrid',
                                    scrollwheel: true,
                                    zoomControl: false,
                                    scaleControl: true,
                                    streetViewControl: false,
                                    fullscreenControl: false,
                                    mapTypeControl: false
                                });
    
                                // Create the search box and link it to the UI element.
                                var input = document.getElementById('pac-input');
                                var searchBox = new google.maps.places.SearchBox(input);
                                map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
    
                                // Bias the SearchBox results towards current map's viewport.
                                map.addListener('bounds_changed', function () {
                                    searchBox.setBounds(map.getBounds());
                                });
    
                                var markers = [];
                                // Listen for the event fired when the user selects a prediction and retrieve
                                // more details for that place.
                                searchBox.addListener('places_changed', function () {
                                    var places = searchBox.getPlaces();
    
                                    if (places.length == 0) {
                                        return;
                                    }
    
                                    // Clear out the old markers.
                                    markers.forEach(function (marker) {
                                        marker.setMap(null);
                                    });
                                    markers = [];
    
                                    // For each place, get the icon, name and location.
                                    var bounds = new google.maps.LatLngBounds();
                                    places.forEach(function (place) {
                                        if (!place.geometry) {
                                            console.log("Returned place contains no geometry");
                                            return;
                                        }
    
                                        // create infowindow: just while debugging not needed in View
                                        var infowindow = new google.maps.InfoWindow();
    
                                        // create geocoder for address
                                        var geocoder = new google.maps.Geocoder();
    
                                        // Create a marker for each place.
                                        markers.push(new google.maps.Marker({
                                            map: map,
                                            //icon: "/Content/icons/01.png",
                                            title: place.name,
                                            position: place.geometry.location,
                                            draggable: true
                                        }));
    
                                        // Add listeners to marker:
                                        // click: opens infowindow
                                        markers[0].addListener('click', function () {
                                            infowindow.open(map, markers[0]);
                                            infowindow.setContent(place.name + ': ' + place.geometry.location);
                                            infowindow.open(map, this);
    
                                            // Add listeners to map
                                            google.maps.event.addListener(markers[0], 'dragend', function (evt) {
                                                infowindow.setContent('Lat: ' + evt.latLng.lat() + '       Lng: ' + evt.latLng.lng());
                                                infowindow.open(map, this);
    
                                                map.setCenter(markers[0].getPosition());
                                                markers[0].setMap(map);
                                                map.setTilt(0);
                                                map.setZoom(20);
    
                                                // update return values
                                                // gLat, gLong, gAddr are global variables
                                                gLat = evt.latLng.lat();
                                                gLong = evt.latLng.lng();
    
                                                // get address
                                                var latlng = { lat: parseFloat(gLat), lng: parseFloat(gLong) };
                                                geocoder.geocode({ 'location': latlng }, function (results, status) {
                                                    if (status === 'OK') {
                                                        if (results[0]) { gAddr = results[0].formatted_address } else {
                                                            gAddr = 'NotFound';
                                                        }
                                                    }
                                                });
    
                                            });
    
                                        });
    
                                        if (place.geometry.viewport) {
                                            // Only geocodes have viewport.
                                            bounds.union(place.geometry.viewport);
                                        } else {
                                            bounds.extend(place.geometry.location);
                                        }
                                    });
                                    map.fitBounds(bounds);
                                });
    
                            }
    
    
    
                        </script>
    
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-secondary" data-dismiss="modal">Chiudi</button>
                        <button type="button" class="btn btn-primary" onclick="updFields(gLat, gLong, gAddr)">Salva</button>
                    </div>
                </div>
            </div>
        </div>
    }
    
    
    
    <script>
    
        $('#findInModal').on('show.bs.modal', function () { 
        })
    
        function updFields(lat,lng, addr) {
            //alert('Lat: ' + lat + '\nLng: ' + lng + '\nAddr: ' + addr);
            //document.getElementById("Address").value = addr;
            //document.getElementById("Latitude").value = lat;
            //document.getElementById("Longitude").value = lng;
            $('#Address').val(addr);
            $('#Latitude').val(lat);
            $('#Longitude').val(lng);
        }
    
    </script>
    

    infowindowalerts 只是在开发中,但不是最终解决方案的一部分。

    基本上,我实现了一个带有自动完成和放置服务的谷歌地图搜索框,以及一个从协调器检索地址的地理编码器。为此,我添加了一个更新隐藏字段的函数。视图的代码要复杂得多因为它包含与地图中位置无关的其他字段,并且可以手动修改字段,但基本上这是代码的主干。

    我想发布图片,我的 APIkey 似乎已超出配额。

    【讨论】:

      猜你喜欢
      • 2014-06-07
      • 1970-01-01
      • 1970-01-01
      • 2012-11-26
      • 1970-01-01
      • 1970-01-01
      • 2012-10-10
      • 2012-11-26
      • 1970-01-01
      相关资源
      最近更新 更多