Using maxBounds to stop panning in Leaflet with angular-leaflet-directive - angularjs

Now that I have my AngularJS application running, I'm trying to restrict LeafletJS map panning as described in this Mapbox document. The issue is that I am using angular-leaflet-directive and my existing code is written to create the map using the leaflet directive in my AngularJS template. So the existing map is defined in this fashion:
<leaflet id="mymap" markers="markers" center="center" width="100%" height="380px"></leaflet>
How do I getBounds() and setMaxBounds() in a situation like this, where I never explicitly did a call to new L.map('leaflet', {...}))?

bounds and maxBounds properties could be set via angular-leaflet-directive using maxBounds and bounds directives respectively, for example:
<leaflet markers="markers" maxbounds="boundsInfo" bounds="boundsInfo"></leaflet>
where bounds should be specified in the following format:
$scope.boundsInfo = {'northEast': {'lat': 40.774, 'lng': -74.125},'southWest': {'lat': 40.712, 'lng': -74.227}};
Example
angular.module("demoapp", ["leaflet-directive"])
.controller("CustomizedMarkersController", ['$scope','leafletData', function ($scope, leafletData) {
$scope.boundsInfo = {'northEast': {'lat': 40.774, 'lng': -74.125},'southWest': {'lat': 40.712, 'lng': -74.227}};
$scope.markers = [];
leafletData.getMap().then(function (map) {
console.log(map.getBounds());
});
}]);
.angular-leaflet-map {
width: 640px;
height: 480px;
}
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.0.1/dist/leaflet.css" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
<script type="text/javascript" src="https://code.angularjs.org/1.2.2/angular.js"></script>
<script type="text/javascript" src="https://tombatossals.github.io/angular-leaflet-directive/dist/angular-leaflet-directive.js"></script>
<script src="https://unpkg.com/leaflet#1.0.1/dist/leaflet.js"></script>
<div ng-app="demoapp" ng-controller="CustomizedMarkersController">
<leaflet markers="markers" maxbounds="boundsInfo" bounds="boundsInfo" maxZoom="19" minZoom="10"></leaflet>
</div>

Related

Google Maps API gesture handling not working with AngularJS Material

(EDIT: When you use plain Google Maps API with AngularJS Material the problem is the same.)
When I use at the same time in my AngularJS app:
NgMap (https://github.com/allenhwkim/angularjs-google-maps)
AngularJS Material (https://github.com/angular/material)
Maps don't work properly on mobile (on desktop it is ok) - the problem is with touch gestures. Example:
https://incampo.pl/map2.html - (test on mobile!)
but when I don't use material:
angular.module("incampoApp", ["ngMap"])
instead of:
angular.module("incampoApp", ["ngMap", "ngMaterial"])
it works properly: https://incampo.pl/map.html - (test on mobile!)
My whole example code (JS compiled from typescript):
<!DOCTYPE html>
<html ng-app="incampoApp">
<head>
</head>
<body ng-controller="offerController as vm">
<div map-lazy-load="https://maps.googleapis.com/maps/api/js?key=AIzaSyAyufiB6xUh1SzM7LK2NniXGDPyY__KtP8&callback=initMap">
<ng-map id="map" min-zoom="2" zoom="6" center="52.2,19"></ng-map>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.4/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.4/angular-animate.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.4/angular-aria.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.4/angular-messages.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angular_material/1.1.10/angular-material.min.js"></script>
<script src="//rawgit.com/allenhwkim/angularjs-google-maps/master/build/scripts/ng-map.min.js"></script>
<script>
var IncampoApp;
(function (IncampoApp) {
var OfferController = (function () {
function OfferController(ngMap) {
ngMap.getMap();
}
OfferController.$inject = ["NgMap"];
return OfferController;
}());
IncampoApp.OfferController = OfferController;
})(IncampoApp || (IncampoApp = {}));
</script>
<script>
var IncampoApp;
(function (IncampoApp) {
angular.module("incampoApp", ["ngMap", "ngMaterial"]).controller("offerController", IncampoApp.OfferController);
})(IncampoApp || (IncampoApp = {}));
</script>
</body>
</html>
Do you have any idea why?
I've found the solution here: https://github.com/angular/material/issues/11205
You just need to call $mdGestureProvider.skipClickHijack();
angular.module('myapp', ['ngMaterial', 'ngMessages'])
.config(function($mdGestureProvider) {
// For mobile devices without jQuery loaded, do not
// intercept click events during the capture phase.
$mdGestureProvider.skipClickHijack();
});
Try this :
<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3652.6095451920282!2d90.38946702923724!3d23.72563358206513!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x3755b8dd3d3673e7%3A0xf999f4771c24183e!2sInstitute+of+AppropriateTechnology!5e0!3m2!1sen!2sbd!4v1519796378399" width="100%" height="450" frameborder="0" style="border: 0"></iframe>
This solution may help you if want simple map in your html without (Google map key). Embed Google Map with iframe

Filter Angular List View based on current view of Google Maps

I am using Angular Google maps with a list of markers. As the map zooms in I would like the list to shrink to only show the markers currently in view.
I have created a plunker with some code. Any help on how I could filter the list as the map zooms?
<!DOCTYPE html>
<html ng-app="ngMap">
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<script src="https://maps.google.com/maps/api/js?libraries=placeses,visualization,drawing,geometry,places"></script>
<script src="https://code.angularjs.org/1.3.15/angular.js"></script>
<script src="https://rawgit.com/allenhwkim/angularjs-google-maps/master/build/scripts/ng-map.js"></script>
<script>
angular.module('ngMap').controller('MyCtrl', function() {
var vm=this;
vm.positions =[
{pos:[40.71, -74.15]},
{pos:[40.72, -74.20]},
{pos:[40.73, -74.18]},
{pos:[40.77, -74.19]},
{pos:[40.75, -74.17]},
{pos:[40.76, -74.16]},
{pos:[40.74, -74.20]}
];
vm.showData = function() {
alert(this.data.foo);
}
});
</script>
</head>
<body>
<div ng-controller="MyCtrl as vm">
<ng-map zoom="11" center="[40.74, -74.18]">
<marker ng-repeat="p in vm.positions"
position="{{p.pos}}"
title="pos: {{p.pos}}"></marker>
</ng-map>
<div>
<div ng-repeat="p in vm.positions">{{p.pos}}</div>
</div>
</div>
</body>
https://plnkr.co/edit/yyOuciyz5WAEG522eNrJ
As far as I can tell from the documentation, there is no directive or configuration that will do this for you.
I created the following work-around that will filter the positions any time the bounds of the map change (filtering out those positions which do not fall between the bounds of the map), which I believe is what you're after.
UPDATE 10/23/18
Here is a better solution ---> https://embed.plnkr.co/pe6Hv5wHknxtwn4F5aST/

Angular material library slider doesn't render visibly

Scripts and CSS loaded in the header:
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/angular_material/1.0.0/angular-material.min.css">
<script src="https://code.jquery.com/jquery-1.10.2.min.js"
integrity="sha256-C6CB9UYIS9UJeqinPHWTHVqh/E1uhG5Twh+Y5qFQmYg="
crossorigin="anonymous">
</script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.js"></script>
<script src="//unpkg.com/angular-ui-router/release/angular-ui-router.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-animate.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-sanitize.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-aria.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angular_material/1.0.0/angular-material.min.js"></script>
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
ng-Material is loaded into the app:
var app = angular.module('app', ['ui.router', 'ngMaterial']);
Using the slider in the html template:
<md-slider min="0" max="7" ng-model="rate" aria-label="rate" id="rateSlider"></md-slider>
The associated controller:
app.controller('theController', ['$scope', "$state", 'uiHandler', function ($scope, $state, uiHandler) {
var handler = new uiHandler($scope, "html/content/theTemplate.html", true);
$scope.showMenu = true;
$scope.percentBid = 2.3;
$scope.topRate = 6;
$scope.rate = 3.2;
}]);
The control appears to render in HTML but none of the elements are actually visible. I can click on them in the page inspector, but I don't think any CSS styles have been properly applied.
Angular Material depends on several modules:
angular (obviously)
angular-animate
angular-aria
Your example lacks the last one. Try including this line:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-aria.js"></script>
See the simplified Plunker example.

How to load Google Map in Materialize Modal?

I am using materializecss and the problem is that Google Map not loading in materialize modal. But other than modal, its working fine. I did everything what i have to do. Any solution for this problem?
Update:
I found the solution for my problem. Actually i was using multiple
view in that modal and placed my map div back of one div using
ng-show. It causes my map to not display. But placing map div in
front of all other div fixed my issue. :)
When the modal shows up, it re-sizes its content to fit into it. So your Google map component's size is changed and as a result, it just needs to be refreshed.
Just add the following code in your <script> tag.
$('.modal-trigger').leanModal({
ready: function() {
var map = document.getElementById("googleMap");
google.maps.event.trigger(map, 'resize');
}
});
That should do it :)
=== EDIT ===
I've added a sample for what i think might help you. This sample initializes the map object when the page loads, and it uses the same object in the model.
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link href="css/materialize.css" type="text/css" rel="stylesheet" media="screen,projection" />
<link href="http://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<script src="js/jquery-2.2.0.js" type="text/javascript"></script>
<script src="js/materialize.js" type="text/javascript"></script>
<script src="http://maps.googleapis.com/maps/api/js"></script>
<script>
function initialize() {
var mapProp = {
center: new google.maps.LatLng(51.508742, -0.120850),
zoom: 5,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("googleMap"), mapProp);
}
google.maps.event.addDomListener(window, 'load', initialize);
$(document).ready(function () {
$('.modal-trigger').leanModal({
ready: function () {
var map = document.getElementById("googleMap");
google.maps.event.trigger(map, 'resize');
}
});
});
</script>
</head>
<body>
<a href="#mapmodel" class="modal-trigger blue z-depth-1 waves-effect waves-light btn-floating">
<i class="red material-icons">location_on</i>
</a>
<div id="mapmodel" class="modal modal-fixed-footer">
<div class="modal-content">
<h4>Test</h4>
<div id="googleMap" style="width:500px;height:380px;"></div>
</div>
<div class="modal-footer">
Got it
</div>
</div>
</body>
</html>

Angular materials : Basic Usage template

I would very much like to integrate in my angular app the Basic Usage template
from Angular Materials.
I really like the transition effect when the <> is clicked.
I already did a search for that directive on their website but did not find it. The closest thing I managed to find is the Toolbar, but it's slightly different in the way that the upper corners are not rounded. Also, using a simple ng-show, will not provided that transition.
Any suggestions on how to achieve this?
You can do that with angular animations which is just some simple CSS with transitions. And you are on the right track with md-toolbar. The demos use it, you just need to set some CSS to round the top corners.
md-card md-toolbar {
border-radius: 3px 3px 0 0;
}
Now add some content below the md-toolbar that you want to toggle and use ng-show on it.
<div class="toggle-content" ng-show="open">
The toggled content!
</div>
Then just check the ngShow documentation on how to animate it with CSS. What you want to animate here is the height of the toogle-content element. When it is hidden, height: 0 is applied, otherwise height: 200px.
.toggle-content {
height: 200px;
background: red;
}
.toggle-content.ng-hide-add, .toggle-content.ng-hide-remove {
transition: height linear 0.5s;
}
.toggle-content.ng-hide {
height: 0;
}
And of course you need a md-button in the toolbar that toggles the content.
<md-button ng-click="open = !open">
Toggle
</md-button>
Complete example: http://codepen.io/kuhnroyal/pen/XXZPrE
You need to implement something akin to the slideToggle() method in jquery. The Angular Slideables directive provides this functionality.
The straight corners are a custom style implemented in addition to the md-toolbar directive.
It turns out this is the closest thing that I managed to find that suits my needs.
'use strict';
angular.module('ui', ['ui.bootstrap']);
(function() {
angular.module('ui', [
"ui.bootstrap",
"ngAnimate"
]);
var module = angular.module("ui");
module.controller("controller", function($scope) {
var model = this;
model.oneAtATime = true;
model.Operators = [{
ReportItemName: "asd"
}, {
ReportItemName: "fds"
}];
});
}());
<!DOCTYPE html>
<html ng-app="ui">
<head>
<link data-require="bootstrap-css#3.1.1" data-semver="3.1.1" rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" />
<script data-require="angular.js#1.4.8" data-semver="1.4.8" src="https://code.angularjs.org/1.4.8/angular.js"></script>
<script data-require="angular-animate#1.4.8" data-semver="1.4.8" src="https://code.angularjs.org/1.4.8/angular-animate.js"></script>
<script data-require="jquery#*" data-semver="2.1.4" src="https://code.jquery.com/jquery-2.1.4.js"></script>
<script data-require="bootstrap#3.1.1" data-semver="3.1.1" src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script data-require="ui-bootstrap#0.14.3" data-semver="0.14.3" src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.14.3/ui-bootstrap.js"></script>
<script data-require="ui-bootstrap-tpls-0.11.2.min.js#0.14.3" data-semver="0.14.3" src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.14.3/ui-bootstrap-tpls.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<div ng-controller="controller as model">
<uib-accordion close-others="model.oneAtATime">
<uib-accordion-group heading="Custom template">
<uib-accordion-heading>
I can have markup, too! <i class="pull-right glyphicon" ng-class="{'glyphicon-chevron-down': status.open, 'glyphicon-chevron-right': !status.open}"></i>
</uib-accordion-heading>
<h1>Some Content</h1>
</uib-accordion-group>
</uib-accordion>
</div>
</body>
</html>
Other solutions that provide out-of-the-box functionality are very much welcomed.

Resources