Javascript Google Maps API V3标记群集,带有可筛选标记
关于Stackoverflow有很多问题,人们都很乐意帮助解决MarkerClusterer的问题,但是,我正在使用Github上Twilliamson90的一个伟大的小项目。基本上,它允许我对标记进行一些良好的过滤,并允许我链接一些良好的外部数据集 但我现在的问题是,我有太多的数据,无法轻松地显示在页面上,而不会显得太拥挤。显而易见的解决方案是添加标记集群——不幸的是,我发现它没有那么容易 我已经学习了好几个教程,但我就是不能让它和过滤一起工作 我已经在下面粘贴了javascript,非常感谢您的帮助。非常好Javascript Google Maps API V3标记群集,带有可筛选标记,javascript,google-maps,google-maps-api-3,Javascript,Google Maps,Google Maps Api 3,关于Stackoverflow有很多问题,人们都很乐意帮助解决MarkerClusterer的问题,但是,我正在使用Github上Twilliamson90的一个伟大的小项目。基本上,它允许我对标记进行一些良好的过滤,并允许我链接一些良好的外部数据集 但我现在的问题是,我有太多的数据,无法轻松地显示在页面上,而不会显得太拥挤。显而易见的解决方案是添加标记集群——不幸的是,我发现它没有那么容易 我已经学习了好几个教程,但我就是不能让它和过滤一起工作 我已经在下面粘贴了javascript,非常感谢
var TEST_MAP = 'custom_style';
var myMap = function() {
var featureOpts = [
{
stylers: [
{ hue: '#782B8B' },
{ visibility: 'simplified' },
{ gamma: 0.5 },
{ weight: 0.5 }
]
},
{
elementType: 'labels',
stylers: [
{ visibility: 'off' }
]
},
{
featureType: 'water',
stylers: [
{ color: '#782B8B' }
]
}
];
var options = {
zoom: 7,
center: new google.maps.LatLng(53.967397, -2.043457),
streetViewControl: false,
zoomControlOptions: {
style: google.maps.ZoomControlStyle.SMALL
},
mapTypeControl: false,
mapTypeControlOptions: {
mapTypeIds: [TEST_MAP]
},
mapTypeId: TEST_MAP
}
/*
Load the map then markers
@param object settings (configuration options for map)
@return undefined
*/
function init(settings) {
map = new google.maps.Map(document.getElementById( settings.idSelector ), options);
var styledMapOptions = {
name: 'Custom Style'
};
var customMapType = new google.maps.StyledMapType(featureOpts, styledMapOptions);
map.mapTypes.set(TEST_MAP, customMapType);
markerLocation = settings.markerLocation;
loadMarkers();
}
/*
=======
MARKERS
=======
*/
markers = {};
markerList = [];
/*
Load markers onto the Google Map party a provided array or demo personData (data.js)
@param array personList [optional] (list of people to load)
@return undefined
*/
function loadMarkers(personList) {
// optional argument of person
var people = ( typeof personList !== 'undefined' ) ? personList : personData;
var j = 1; // for lorempixel
for( i=0; i < people.length; i++ ) {
var person = people[i];
// if its already on the map, dont put it there again
if( markerList.indexOf(person.id) !== -1 ) continue;
var lat = person.lat,
lng = person.lng,
markerId = person.id;
var infoWindow = new google.maps.InfoWindow({
maxWidth: 500
});
var iconImage = {
url: person.markerIcon,
size: new google.maps.Size(30, 40),
origin: new google.maps.Point(0,0),
anchor: new google.maps.Point(0,40)
};
var marker = new google.maps.Marker({
position: new google.maps.LatLng( lat, lng ),
title: person.name,
markerId: markerId,
icon: iconImage,
map: map
});
markers[markerId] = marker;
markerList.push(person.id);
var MarkerCluster = new MarkerClusterer(TEST_MAP, markers);
var content = ['<div class="iw"><img src="', person.image, '">', '<div class="iw-text"><strong>', person.name, '</strong><br><strong>Applications:</strong> ', person.applications, '<br><strong>SIC Sub Class:</strong> ', person.sicSubClass, '<br><strong>Constituency:</strong> ', person.constituency, '<br><strong>Stream:</strong> ', person.stream, '<br><strong>Town:</strong> ', person.town, '<br><strong>Start date:</strong> ', person.startDate, '<br><strong>Offer grant:</strong> £', person.grant, '<br><strong>Offer cost:</strong> £', person.cost, '<br><strong>Payments to date:</strong> £', person.payments, '<br><a target="blank_" href="', person.url, '">', person.url, '</a></div></div>'].join('');
google.maps.event.addListener(marker, 'click', (function (marker, content) {
return function() {
infoWindow.setContent(content);
infoWindow.open(map, marker);
}
})(marker, content));
}
}
/*
Remove marker party map and our list of current markers
@param int id (id of the marker element)
@return undefined
*/
function removePersonMarker(id) {
if( markers[id] ) {
markers[id].setMap(null);
loc = markerList.indexOf(id);
if (loc > -1) markerList.splice(loc, 1);
delete markers[id];
}
}
/*
======
FILTER
======
*/
// default all filters off
var filter = {
applications: 0,
constituency: 0,
town: 0,
stream: 0,
startDate: 0,
party: 0
}
var filterMap;
/*
Helper function
@param array a (array of arrays)
@return array (common elements party all arrays)
*/
function reduceArray(a) {
r = a.shift().reduce(function(res, v) {
if (res.indexOf(v) === -1 && a.every(function(a) {
return a.indexOf(v) !== -1;
})) res.push(v);
return res;
}, []);
return r;
}
/*
Helper function
@param string n
@return bool
*/
function isInt(n) {
return n % 1 === 0;
}
/*
Decides which filter function to call and stacks all filters together
@param string filterType (the property that will be filtered upon)
@param string value (selected filter value)
@return undefined
*/
function filterCtrl(filterType, value) {
// result array
var results = [];
if( isInt(value) ) {
filter[filterType] = parseInt(value);
} else {
filter[filterType] = value;
}
for( k in filter ) {
if( !filter.hasOwnProperty(k) && !( filter[k] !== 0 ) ) {
// all the filters are off
loadMarkers();
return false;
} else if ( filter[k] !== 0 ) {
// call filterMap function and append to r array
results.push( filterMap[k]( filter[k] ) );
} else {
// fail silently
}
}
if( filter[filterType] === 0 ) results.push( personData );
/*
if there is 1 array (1 filter applied) set it,
else find markers that are common to every results array (pass every filter)
*/
if( results.length === 1 ) {
results = results[0];
} else {
results = reduceArray( results );
}
loadMarkers( results );
}
/*
The keys in this need to be mapped 1-to-1 with the keys in the filter variable.
*/
filterMap = {
applications: function( value ) {
return filterIntsLessThan('applications', value);
},
town: function( value ) {
return filterByString('town', value);
},
constituency: function( value ) {
return filterByString('constituency', value);
},
stream: function( value ) {
return filterByString('stream', value);
},
party: function( value ) {
return filterByString('party', value);
},
startDate: function( value ) {
return filterByString('startDate', value);
}
}
/*
Filters marker data based upon a string match
@param string dataProperty (the key that will be filtered upon)
@param string value (selected filter value)
@return array (applicants that made it through the filter)
*/
function filterByString( dataProperty, value ) {
var applicants = [];
for( var i=0; i < personData.length; i++ ) {
var person = personData[i];
if( person[dataProperty] == value ) {
applicants.push( person );
} else {
removePersonMarker( person.id );
}
}
return applicants;
}
/*
Filters out integers that are under the provided value
@param string dataProperty (the key that will be filtered upon)
@param int value (selected filter value)
@return array (applicants that made it through the filter)
*/
function filterIntsLessThan( dataProperty, value ) {
var applicants = [];
for( var i=0; i < personData.length; i++ ) {
var person = personData[i];
if( person[dataProperty] > value ) {
applicants.push( person )
} else {
removePersonMarker( person.id );
}
}
return applicants;
}
// Takes all the filters off
function resetFilter() {
filter = {
applications: 0,
constituency: 0,
town: 0,
stream: 0,
startDate: 0,
party: 0
}
}
return {
init: init,
loadMarkers: loadMarkers,
filterCtrl: filterCtrl,
resetFilter: resetFilter
};
}();
$(function() {
var mapConfig = {
idSelector: 'map-canvas'
}
myMap.init( mapConfig );
$('.load-btn').on('click', function() {
var $this = $(this);
// reset everything
$('select').val(0);
myMap.resetFilter();
myMap.loadMarkers();
if( $this.hasClass('is-success') ) {
$this.removeClass('is-success').addClass('is-default');
}
});
$('.applications-select').on('change', function() {
myMap.filterCtrl('applications', this.value);
});
$('.town-select').on('change', function() {
myMap.filterCtrl('town', this.value);
});
$('.constituency-select').on('change', function() {
myMap.filterCtrl('constituency', this.value);
});
$('.stream-select').on('change', function() {
myMap.filterCtrl('stream', this.value);
});
$('.party-select').on('change', function() {
myMap.filterCtrl('party', this.value);
});
$('.startDate-select').on('change', function() {
myMap.filterCtrl('startDate', this.value);
});
});
var测试映射='custom_style';
var myMap=函数(){
变量特性选项=[
{
样式:[
{色调:'#782B8B'},
{可见性:'简化'},
{gamma:0.5},
{重量:0.5}
]
},
{
elementType:'标签',
样式:[
{可见性:“关闭”}
]
},
{
功能类型:“水”,
样式:[
{颜色:'#782B8B'}
]
}
];
变量选项={
缩放:7,
中心:新google.maps.LatLng(53.967397,-2.043457),
街景控制:错误,
ZoomControl选项:{
样式:google.maps.ZoomControlStyle.SMALL
},
mapTypeControl:false,
mapTypeControlOptions:{
MapTypeId:[测试地图]
},
mapTypeId:TEST\u映射
}
/*
加载地图,然后单击标记
@参数对象设置(地图的配置选项)
@返回未定义
*/
函数初始化(设置){
map=new google.maps.map(document.getElementById(settings.idSelector),options);
var styledMapOptions={
名称:“自定义样式”
};
var customMapType=new google.maps.StyledMapType(featureOpts,styledMapOptions);
map.mapTypes.set(TEST_map,customMapType);
markerLocation=settings.markerLocation;
loadMarkers();
}
/*
=======
标记
=======
*/
标记={};
markerList=[];
/*
将标记加载到谷歌地图甲方提供的数组或演示personData(data.js)上
@param array personList[可选](要加载的人员列表)
@返回未定义
*/
函数加载标记(personList){
//人的选择论元
var people=(typeof personList!=“未定义”)?personList:personData;
var j=1;//对于lorempixel
对于(i=0;i,person.name,应用程序:,person.Applications,
SIC子类:,person.sicSubClass,
选区:,person.section,
流:,person.Stream,
城镇:,person.Town,
开始日期:,person.startDate,
提供补助金:£;,person.grant,
提供成本:£;,person.cost,
迄今为止的付款:£;,person.Payments,
'];
google.maps.event.addListener(标记,'单击',(函数(标记,内容){
返回函数(){
infoWindow.setContent(content);
信息窗口。打开(地图、标记);
}
})(标记、内容);
}
}
/*
删除标记方地图和我们的当前标记列表
@param int id(标记元素的id)
@返回未定义
*/
函数removePersonMarker(id){
如果(标记[id]){
标记[id].setMap(空);
loc=标记列表indexOf(id);
如果(loc>-1)标记列表拼接(loc,1);
删除标记[id];
}
}
/*
======
滤器
======
*/
//默认关闭所有过滤器
变量过滤器={
应用程序:0,
选区:0,
城镇:0,,
流:0,
起始日期:0,,
缔约方:0
}
var滤波器映射;
/*
辅助函数
@参数数组a(数组的数组)
@返回数组(所有数组的公共元素)
*/
功能还原雷(a){
r=a.shift().reduce(函数(res,v){
if(res.indexOf(v)==-1&&a.every(函数(a){
返回a.indexOf(v)!=-1;
}))res.push(v);
返回res;
}, []);
返回r;
}
/*
辅助函数
@参数字符串n
@返回布尔
*/
函数isInt(n){
返回n%1==0;
}
/*
决定调用哪个筛选器函数并将所有筛选器堆叠在一起
@param string filterType(将根据其进行筛选的属性)
@参数字符串值
new MarkerClusterer(map,markers);
<script>
$(document).ready(function(){
ShowHelperMap();
});
function ShowHelperMap() {
var ctr =new google.maps.LatLng(17.3660, 78.4760);
var Locations=JSON.parse('[{"Lat":"17.5048667","Lng":"78.4143219"},{"Lat":"17.501313","Lng":"78.4286192"},{"Lat":"17.4865184","Lng":"78.449826"},{"Lat":"17.4963517","Lng":"78.4326133"},{"Lat":"17.4939323","Lng":"78.4420625"},{"Lat":"17.4654334","Lng":"78.4554779"},{"Lat":"17.465164","Lng":"78.45617"},{"Lat":"17.4667402","Lng":"78.4576088"},{"Lat":"17.5043837","Lng":"78.4155832"}]');
var mapOptions = {
center: ctr,
zoom: parseInt(10),
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: false,
streetViewControl: false
};
var myInfoWindow = new google.maps.InfoWindow;
var locationMap = new google.maps.Map(document.getElementById("map"), mapOptions);
var l;
var markers=[];
if (Locations && Locations.length > 0) {
for (l = 0; l < Locations.length; l++) {
store = Locations[l];
var centerMarker = new google.maps.Marker({
position: new google.maps.LatLng(parseFloat(store.Lat), parseFloat(store.Lng)),
map: locationMap
});
markers.push(centerMarker);
}
}
new MarkerClusterer(locationMap,markers);
}
<div id="map" style="width:98%;height:100%;margin:0 auto;" ></div>