听一个复选框并在谷歌地图上显示/隐藏圆形(AngularJS)

Posted

技术标签:

【中文标题】听一个复选框并在谷歌地图上显示/隐藏圆形(AngularJS)【英文标题】:Listen to a checkbox and show/hide circle-shape on google-maps (AngularJS) 【发布时间】:2017-10-15 05:04:56 【问题描述】:

我的问题与这个较旧的线程Google Maps v3 setting a circle with editable radius but not center有关

我遇到了和这个人一样的问题,用geocodezip的解决方案解决了我的问题。

但现在没有卡在另一个点上。我有一个名为 byRadius 的复选框,只有当此复选框被标记时,我才想显示圆圈。如果没有,我只想显示标记。但我无法在我的 html 中找到圆圈或标记,所以我不确定如何更改圆圈的可见性。

我在我的复选框上使用了一个侦听器来侦听更改事件,并且在被触发时我想更改可见性。

$scope.$watch('vm.socialMediaFilter.byRadius', function () 
 
  var circle = document.getElementById('circleModal');
  console.log(vm.socialMediaFilter.byRadius);
);

地图的 HTML 标记

<div class="col-xs-12">
  <ng-map id="modalMap" class="gov-map" style="display: block; height: 25vh;"</ng-map>
</div>

what got rendered from controller + html

【问题讨论】:

有什么方法可以让您将对象绑定到 DOM 中的 ng-model 或直接绑定到 $scope,而不是使用 document.getElementById('..') 在 DOM 中“查找”? 圆圈在我的 html 中未定义为形状。因为我需要在不使其可拖动的情况下调整它的大小,所以我需要自己绘制它而不使用 shape 指令。 shape 指令可以调整大小,但默认情况下,如果不使其可拖动,则无法调整大小。我将使用 HTML 编辑我的帖子。创建形状和标记的函数是您可以找到链接线程的函数 那么为什么不能将您在javascript中创建的对象分配给$scope 我将 circle 元素和 radiusWidget 放在我的 $scope 中,并像这样更改了我的监听器$scope.$watch('vm.socialMediaFilter.byRadius', function () if (vm.socialMediaFilter.byRadius) $scope.circle.visible = false; else $scope.circle.visible = true; );但现在我得到了一个例外,即 $scope 在那一刻是未定义的。 如果 $scope 未定义,则在将圆圈添加到 $scope 时,您很可能超出了控制器的范围。您正在做的事情的完整代码示例将是有益的。 【参考方案1】:
(function () 
'use strict';

angular
    .module('kokosGisApp')
    .controller('SocialMediaFilterDialogController', SocialMediaFilterDialogController);

SocialMediaFilterDialogController.$inject = ['Principal', '$timeout', '$rootScope', '$scope', '$stateParams', '$uibModalInstance', 'entity', 'SocialMediaFilter', 'User', 'NgMap'];

function SocialMediaFilterDialogController(Principal, $timeout, $rootScope, $scope, $stateParams, $uibModalInstance, entity, SocialMediaFilter, User, NgMap) 
    var vm = this;
    vm.socialMediaFilter = entity;
    vm.clear = clear;
    vm.save = save;
    vm.users = User.query();

    if (vm.socialMediaFilter.mapInit == 0) 
        vm.socialMediaFilter.type = "Facebook";
        vm.socialMediaFilter.radius = 150;
        vm.socialMediaFilter.address = $rootScope.res[0];
        vm.socialMediaFilter.city = $rootScope.res[1];
        vm.socialMediaFilter.latitude = $rootScope.mouseEventLatLng.lat();
        vm.socialMediaFilter.longitude = $rootScope.mouseEventLatLng.lng();
     else if (vm.socialMediaFilter.mapInit == 1) 
        vm.socialMediaFilter.type = "Facebook";
        vm.socialMediaFilter.radius = 150;
        vm.socialMediaFilter.address = '';
        vm.socialMediaFilter.city = '';
        vm.socialMediaFilter.latitude = 50.875863;
        vm.socialMediaFilter.longitude = 8.0168847;
    


    Principal.identity().then(function (user) 
        vm.socialMediaFilter.user = user;
    );

    $timeout(function () 
        angular.element('.form-group:eq(1)>input').focus();
    );

    function clear() 
        $uibModalInstance.dismiss('cancel');
    

    function save() 

        NgMap.getMap(id: 'modalMap').then(function (map) 
            if (typeof this.map.shapes !== 'undefined') 
                vm.socialMediaFilter.latitude = map.shapes.circleModal.center.lat();
                vm.socialMediaFilter.longitude = map.shapes.circleModal.center.lng();
                vm.socialMediaFilter.radius = map.shapes.circleModal.radius;
             else 
                vm.socialMediaFilter.latitude = map.markers.markerModal.position.lat();
                vm.socialMediaFilter.longitude = map.markers.markerModal.position.lng();
                vm.socialMediaFilter.radius = null;
            
        );
        vm.isSaving = true;
        if (vm.socialMediaFilter.id !== null) 
            SocialMediaFilter.update(vm.socialMediaFilter, onSaveSuccess, onSaveError);
         else 
            SocialMediaFilter.save(vm.socialMediaFilter, onSaveSuccess, onSaveError);
        
    

    function onSaveSuccess(result) 
        $scope.$emit('kokosGisApp:socialMediaFilterUpdate', result);
        $uibModalInstance.close(result);
        vm.isSaving = false;
    

    function onSaveError() 
        vm.isSaving = false;
    

    $scope.$watch('vm.socialMediaFilter.byRadius', function ()
    
        if (vm.socialMediaFilter.byRadius) 
            $scope.circle.visible = false;
         else $scope.circle.visible = true;
    );

    /**
     * A distance widget that will display a circle that can be resized and will
     * provide the radius in km.
     *
     * @param google.maps.Map map The map to attach to.
     *
     * @constructor
     */

    function DistanceWidget(map) 
        this.set('map', map);
        this.set('position', map.getCenter());

        var marker = new google.maps.Marker(
            // draggable: true,  // <-- change to make so position doesn't move
            title: 'Move me!',
            id: 'markerModal'
        );

        // Bind the marker map property to the DistanceWidget map property
        marker.bindTo('map', this);

        // Bind the marker position property to the DistanceWidget position
        // property
        marker.bindTo('position', this);

        // Create a new radius widget
        $scope.radiusWidget = new RadiusWidget();

        // Bind the radiusWidget map to the DistanceWidget map
        $scope.radiusWidget.bindTo('map', this);

        // Bind the radiusWidget center to the DistanceWidget position
        $scope.radiusWidget.bindTo('center', this, 'position');

        // Bind to the radiusWidgets' distance property
        this.bindTo('distance', $scope.radiusWidget);

        // Bind to the radiusWidgets' bounds property
        this.bindTo('bounds', $scope.radiusWidget);
    

    DistanceWidget.prototype = new google.maps.MVCObject();


    /**
     * A radius widget that add a circle to a map and centers on a marker.
     *
     * @constructor
     */
    function RadiusWidget() 
        $scope.circle = new google.maps.Circle(
            strokeWeight: 2,
            color: 'orange',
            visible: true
        );

        // Set the distance property value, default to 10km.
        this.set('distance', 150);

        // Bind the RadiusWidget bounds property to the circle bounds property.
        this.bindTo('bounds', $scope.circle);

        // Bind the circle center to the RadiusWidget center property
        $scope.circle.bindTo('center', this);

        // Bind the circle map to the RadiusWidget map
        $scope.circle.bindTo('map', this);

        // Bind the circle radius property to the RadiusWidget radius property
        $scope.circle.bindTo('radius', this);

        // this.bindTo('byRadius', vm.socialMediaFilter.byRadius);

        // Add the sizer marker
        this.addSizer_();
    

    RadiusWidget.prototype = new google.maps.MVCObject();
    // RadiusWidget.prototype.byRadius_changed = function () 
    //     console.log('dasdas');
    // 


    /**
     * Update the radius when the distance has changed.
     */
    RadiusWidget.prototype.distance_changed = function () 
        this.set('radius', this.get('distance'));
    ;


    /**
     * Add the sizer marker to the map.
     *
     * @private
     */
    RadiusWidget.prototype.addSizer_ = function () 
        var sizer = new google.maps.Marker(
            draggable: true,
            visible: true
        );

        sizer.bindTo('map', this);
        sizer.bindTo('position', this, 'sizer_position');

        var me = this;
        google.maps.event.addListener(sizer, 'drag', function () 
            // As the sizer is being dragged, its position changes.  Because the
            // RadiusWidget's sizer_position is bound to the sizer's position, it will
            // change as well.
            var min = 0.5;
            var max = 2500;
            var pos = me.get('sizer_position');
            var center = me.get('center');
            var distance = google.maps.geometry.spherical.computeDistanceBetween(center, pos);
            if (distance < min) 
                me.set('sizer_position', google.maps.geometry.spherical.computeOffset(center, min, google.maps.geometry.spherical.computeHeading(center, pos)));
             else if (distance > max) 
                me.set('sizer_position', google.maps.geometry.spherical.computeOffset(center, max, google.maps.geometry.spherical.computeHeading(center, pos)));
            
            // Set the circle distance (radius)
            me.setDistance();

        );
    ;


    /**
     * Update the center of the circle and position the sizer back on the line.
     *
     * Position is bound to the DistanceWidget so this is expected to change when
     * the position of the distance widget is changed.
     */
    RadiusWidget.prototype.center_changed = function () 
        var bounds = this.get('bounds');

        // Bounds might not always be set so check that it exists first.
        if (bounds) 
            var lng = bounds.getNorthEast().lng();

            // Put the sizer at center, right on the circle.
            var position = new google.maps.LatLng(this.get('center').lat(), lng);
            this.set('sizer_position', position);
        
    ;


    /**
     * Set the distance of the circle based on the position of the sizer.
     */
    RadiusWidget.prototype.setDistance = function () 
        // As the sizer is being dragged, its position changes.  Because the
        // RadiusWidget's sizer_position is bound to the sizer's position, it will
        // change as well.
        var pos = this.get('sizer_position');
        var center = this.get('center');
        var distance = google.maps.geometry.spherical.computeDistanceBetween(center, pos);

        // Set the distance property for any objects that are bound to it
        this.set('distance', distance);
    ;


    function initMap() 

        NgMap.getMap(id:'modalMap').then(function (map) 
                map.setCenter(new google.maps.LatLng(vm.socialMediaFilter.latitude, vm.socialMediaFilter.longitude));
                var currentCenter = map.getCenter();
                map.setZoom(15);
                google.maps.event.trigger(map, 'resize');
                map.setCenter(currentCenter);
                var distanceWidget = new DistanceWidget(map);

                // google.maps.event.addListener(distanceWidget, 'distance_changed', function () 
                //     displayInfo(distanceWidget);
                // );
                //
                // google.maps.event.addListener(distanceWidget, 'position_changed', function () 
                //     displayInfo(distanceWidget);
                // );
            
        );

    

    google.maps.event.addDomListener(window, 'load', initMap());

)();

这是用作将实体保存到我的数据库的模式的控制器

如果选中了“Suchradius eingrenzen”复选框,我只想显示圆圈。如果没有标记,我只想在中心显示标记。

modal

【讨论】:

好吧...我已经把这个问题搁置了几天,今天再次尝试解决这个问题。据我所知......问题似乎是,RadiusWidget 是私有的,所以我不能使用 $scope。所以现在我的新问题是如何让我的 $scope 可以在其中访问?

以上是关于听一个复选框并在谷歌地图上显示/隐藏圆形(AngularJS)的主要内容,如果未能解决你的问题,请参考以下文章

在谷歌地图上隐藏其他位置

在谷歌地图中隐藏纬度和经度

如何在谷歌地图中显示集群时隐藏标记

在谷歌地图静态api中绘制圆形路径

使折线水平显示在谷歌地图上并将其缩放到中心坐标

根据不同的纬度和长度设置谷歌地图的缩放级别