1function CisMapObject(pMapZoom, pMapCenter, pCityBounds, pHtmlContainer) { 2 var map = false, 3 mapZoom = pMapZoom, 4 mapCenter = pMapCenter, 5 cityBounds = new google.maps.LatLngBounds(new google.maps.LatLng(pCityBounds[0][0], pCityBounds[0][1]), new google.maps.LatLng(pCityBounds[1][0], pCityBounds[1][1])), 6 htmlContainer = pHtmlContainer, 7 geocoder = false, 8 markers = [], 9 metro_marker = null, 10 infoWindows = [], 11 infoWindow = new google.maps.InfoWindow(), 12 zoomCityView = 11, 13 cis_options = {}, 14 addressComponentsOrder = ['route', 'street_number'], 15 addressComponentsUnwanted = ['administrative_area_level_1', 'administrative_area_level_3', 'country', 'postal_code'], 16 self = this; 17 18 this.getMap = function () { 19 return map; 20 }; 21 22 this.setMap = function (gmapObj) { 23 map = gmapObj; 24 }; 25 26 this.getCenter = function () { 27 return mapCenter; 28 }; 29 30 this.getCityBounds = function () { 31 return cityBounds; 32 }; 33 34 this.addMarkers = function (newMarkers) { 35 markers = markers.concat(newMarkers); 36 }; 37 38 this.setMarkerOptions = function (markerId, options) { 39 markers[markerId].setOptions(options); 40 }; 41 42 this.showMarkersInViewport = function (ids) { 43 if (!map) { 44 return; 45 } 46 var marksNotView = []; 47 var marks = []; 48 $.each(ids, function (i, id) { 49 marks.push(markers[id]); 50 if (!map.getBounds().contains(markers[id].getPosition())) { 51 marksNotView.push(id); 52 } 53 }); 54 if (marksNotView.length > 1) { 55 self.fitBoundsWithMarkers(marks); 56 } else if (marksNotView.length == 1) { 57 map.setCenter(markers[marksNotView[0]].getPosition()); 58 } 59 }; 60 61 this.redrawCityBounds = function () { 62 map.fitBounds(cityBounds); 63 }; 64 65 this.init = function (initOptions, initialized, tilesloaded) { 66 self.setOptions(initOptions); 67 68 if ("function" == typeof (initialized)) { 69 initialized(); 70 } 71 if ("function" == typeof (tilesloaded)) { 72 google.maps.event.addListenerOnce(map, 'tilesloaded', () => tilesloaded()); 73 } 74 }; 75 76 this.extractLatLngInfo = function (info, callback) { 77 var streetInfo; 78 var addressDetails; 79 var address = { 80 admn_area: null, 81 sub_admn_area: null, 82 city: null, 83 street: null, 84 house: null, 85 house_add: null, 86 post_index: null 87 }; 88 89 addressDetails = info[0].address_components; 90 91 for (var i = 0; i < addressDetails.length; i++) { 92 if ($.inArray('street_number', addressDetails[i].types) + 1) { 93 var houseInfo; 94 if (addressDetails[i].short_name.indexOf('/') + 1) { 95 houseInfo = addressDetails[i].short_name.split('/'); 96 address.house = houseInfo[0]; 97 address.house_add = houseInfo[1]; 98 } else { 99 address.house = parseInt(addressDetails[i].short_name); 100 address.house_add = addressDetails[i].short_name.replace(new RegExp(address.house, 'g'), ''); 101 } 102 continue; 103 } 104 if ($.inArray('sublocality', addressDetails[i].types) + 1) { 105 address.sub_admn_area = addressDetails[i].short_name; 106 continue; 107 } 108 if ($.inArray('locality', addressDetails[i].types) + 1) { 109 address.city = addressDetails[i].short_name; 110 continue; 111 } 112 if ($.inArray('administrative_area_level_1', addressDetails[i].types) + 1) { 113 address.admn_area = addressDetails[i].short_name; 114 continue; 115 } 116 if ($.inArray('postal_code', addressDetails[i].types) + 1) { 117 address.post_index = addressDetails[i].short_name; 118 continue; 119 }
120 if ($.inArray('route', addressDetails[i].types) + 1) { 121 streetInfo = addressDetails[i].short_name; 122 if (streetInfo != 'Unnamed Road') { 123 address.street = streetInfo; 124 } 125 continue; 126 } 127 } 128 129 markers[0].balloonContent = info[0].formatted_address; 130 infoWindow.setContent(markers[0].balloonContent); 131 self.panToMarker(0); 132 133 var position = markers[0].getPosition(); 134 if (typeof (callback) == 'function') { 135 callback(address, [position.lat(), position.lng()]); 136 } 137 }; 138 139 this.getLatLngInfo = function (position, callback) { 140 if (!geocoder) geocoder = new google.maps.Geocoder(); 141 geocoder.geocode({ 142 "location": position 143// "bounds": cityBounds 144 }, function (res, status) { 145 if (status == google.maps.GeocoderStatus.OK) { 146 if (typeof (callback) == 'function') { 147 callback(res); 148 } 149 } else { 150 151 } 152 }); 153 154 }; 155 156 this.getMarkerPositionInfo = function (markerId, callback) { 157 self.getLatLngInfo(markers[markerId].getPosition(), callback); 158 }; 159 160 this.addMarker = function (data, windowContent, markerCallBack) { 161 var infowindowContent; 162 if (!map) return; 163 if ('function' == typeof (windowContent)) { 164 infowindowContent = windowContent(data); 165 } else { 166 infowindowContent = windowContent; 167 } 168 169 if (!data.lat || !data.lng) { 170 return; 171 } 172 var newMarker = new google.maps.Marker({ 173 position: new google.maps.LatLng(data.lat, data.lng), 174 map: map, 175 icon: data.icon, 176 title: data.title, 177 draggable: data.draggable || false 178 }); 179 180 if (data.hasOwnProperty('zIndex')) { 181 newMarker.setZIndex(data.zIndex); 182 } 183 184 markers.push(newMarker); 185 if (infowindowContent != undefined) { 186 newMarker.balloonContent = infowindowContent; 187 google.maps.event.addListener(markers[markers.length - 1], "click", function (e) { 188 if ('function' == typeof markerCallBack) { 189 markerCallBack(e, markers, markers.indexOf(newMarker)); 190 } else { 191 infoWindow.setContent(this.balloonContent); 192 infoWindow.open(map, this); 193 } 194 }); 195 } 196 197 return markers.length - 1; 198 }; 199 200 this.parseList = function (addresses, dataAttribute, markerIdAttribute, callback, searchDoneCallback, markerCallback) { 201 if (!addresses || !dataAttribute || !markerIdAttribute) { 202 return; 203 } 204 205 var markerId = null; 206 var hasSearchDoneCallback = (typeof searchDoneCallback === "function"); 207 $.each(addresses, function (i, el) { 208 var data = $(el).data(dataAttribute); 209 if (data.lat != null && data.lng != null) { 210 var success = false; 211 markerId = self.addMarker(data, data.balloonContent, markerCallback); 212 if (typeof markerId !== "undefined") { 213 $(el).data(markerIdAttribute, markerId); 214 success = true; 215 } 216 if (hasSearchDoneCallback) { 217 searchDoneCallback(el, success); 218 } 219 } else { 220 self.searchAddress(data.address, function (res) { 221 markerId = res[0][0]; 222 $(el).data(markerIdAttribute, markerId); 223 markers[markerId].setIcon(data.icon); 224 if (hasSearchDoneCallback) { 225 searchDoneCallback(el, true); 226 } 227 }, function () { 228 if (hasSearchDoneCallback) { 229 searchDoneCallback(el, false); 230 } 231 }); 232 } 233 }); 234 if (typeof callback === "function") { 235 callback(); 236 } 237 }; 238 239 this.addUserMarkers = function (markersData, center) { 240 var latlngBounds = new google.maps.LatLngBounds(); 241 center = center || false; 242 var marker = {}; 243 $.each(markersData, function (i, el) { 244 if (typeof el.position == "string") { 245 self.searchAddress(el.position, 246 function (idx) { 247 var marker = markers[idx[0][0]];
248 marker.setMap(map); 249 marker.setIcon(el.icon); 250 251 } 252 ); 253 } else if (typeof el.position == "object") { 254 marker = { 255 lat: el.position[0], 256 lng: el.position[1], 257 icon: el.icon, 258 title: el.title 259 }; 260 self.addMarker(marker, el.address); 261 } 262 }); 263 if (center) { 264 for (var i = 0; i < markers.length; i++) { 265 latlngBounds.extend(markers[i].getPosition()); 266 } 267 map.setCenter(latlngBounds.getCenter(), map.fitBounds(latlngBounds)); 268 } 269 }; 270 271 function addMarkerSaveCoordinatesListener(marker, saveCallback) { 272 if ("function" == typeof (saveCallback)) { 273 google.maps.event.addListener(marker, "dragend", function () { 274 saveCallback(this.getPosition().lat(), this.getPosition().lng()); 275 }); 276 } 277 } 278 279 this.searchAddress = function (address, callback, faultCallback, geocoderOptions, markerCallBack) { 280 if (!map) return; 281 var retValue = []; 282 var strictBounds; 283 if (geocoderOptions != undefined) { 284 strictBounds = geocoderOptions.strictBounds || false; 285 delete geocoderOptions.strictBounds; 286 } 287 if (!geocoder) geocoder = new google.maps.Geocoder(); 288 geocoder.geocode($.extend({ 289 "address": address, 290 "bounds": cityBounds 291 }, geocoderOptions), function (results, status) { 292 if (status == google.maps.GeocoderStatus.OK) { 293// var first = true; 294 for (var i = 0; i < results.length; i++) { 295 var searchResult = results[i]; 296// if (cityBounds.contains(searchResult.geometry.location)) { 297// address_components Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ Ð¾ÑÑоÑÑиÑÐ¾Ð²Ð°Ð½Ñ Ð² поÑÑдке, как они ÑаÑÐ¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ñ Ð² addressComponentsOrder 298// а вÑе оÑÑалÑнÑе оÑÑаÑÑÑÑ Ð² поÑÑдке, возвÑаÑаемом geocoder 299 searchResult.address_components.sort(function (a, b) { 300 var aIdx = -1, bIdx = -1; 301 for (var l = 0; l < addressComponentsOrder.length && (aIdx < 0 || bIdx < 0); l++) { 302 if (aIdx < 0 && a.types.in_array(addressComponentsOrder[l])) aIdx = l; 303 if (bIdx < 0 && b.types.in_array(addressComponentsOrder[l])) bIdx = l; 304 } 305 if (aIdx < 0 || bIdx < 0) return 0; 306 if (aIdx > bIdx) return 1; 307 return -1; 308 }); 309// не бÑдем оÑобÑажаÑÑ address_components, пеÑеÑиÑленнÑе в addressComponentsUnwanted 310 var displayAddress = []; 311 for (var j = 0; j < searchResult.address_components.length; j++) { 312 var addressComponent = searchResult.address_components[j]; 313 var includeIntoDisplayAddress = true; 314 for (var k = 0; k < addressComponent.types.length && includeIntoDisplayAddress; k++) { 315 if (addressComponentsUnwanted.in_array(addressComponent.types[k])) includeIntoDisplayAddress = false; 316 } 317 if (includeIntoDisplayAddress) displayAddress.push(addressComponent.long_name); 318 } 319 displayAddress = displayAddress.join(', '); 320 321 if (strictBounds && 322 !cityBounds.contains(results[i].geometry.location)) { 323 continue; 324 } 325 self.addMarker({ 326 lat: results[i].geometry.location.lat(), 327 lng: results[i].geometry.location.lng(), 328 title: displayAddress 329 }, displayAddress, markerCallBack); 330 retValue.push([markers.length - 1, displayAddress]); 331 } 332 if (retValue.length > 0) { 333 "function" === typeof callback && callback(retValue, "GEOCODER_RESULTS"); 334 } else { 335 "function" === typeof faultCallback && faultCallback("ZERO_RESULTS"); 336 } 337 } else if (status == google.maps.GeocoderStatus.ZERO_RESULTS) { 338 "function" === typeof faultCallback && faultCallback("ZERO_RESULTS"); 339 } else { 340 "function" === typeof faultCallback && faultCallback(); 341 } 342 }); 343 }; 344 345 this.clear = function () { 346 if (!map) { 347 return; 348 } 349 jQuery.each(infoWindows, function (key, value) { 350 value.close(); 351 }); 352 jQuery.each(markers, function (key, value) { 353 value.setMap(null); 354 }); 355 infoWindows.length = 0; 356 markers.length = 0; 357 }; 358 359 this.showMarker = function (markerId) {
360 markers[markerId].setMap(map); 361 }; 362 363 this.hideMarkers = function () { 364 jQuery.each(markers, function (key, value) { 365 value.setMap(null); 366 }); 367 }; 368 369 this.getMarker = function (index) { 370 return markers[index]; 371 }; 372 373 this.getMarkers = function () { 374 return markers; 375 }; 376 377 this.panToWindow = function (windowIdx) { 378 if (!map) { 379 return; 380 } 381 if (!windowIdx) { 382 return; 383 } 384 jQuery.each(windowIdx, function (key, value) { 385 if (infoWindows[value]) infoWindows[value].open(map); 386 }); 387 map.panTo(infoWindows[windowIdx[0]].getPosition()); 388 }; 389 390 this.panToMarker = function (placemarkIdx) { 391 if (!map) { 392 return; 393 } 394 let marker = markers[placemarkIdx]; 395 if (!marker) { 396 return; 397 } 398 map.panTo(marker.position); 399 if (cis_options.autoOpenMarkers) { 400 var idleListener = google.maps.event.addListener(map, "idle", function () { 401 google.maps.event.trigger(marker, 'click'); 402 google.maps.event.removeListener(idleListener); 403 }); 404 } 405 marker.setAnimation(google.maps.Animation.BOUNCE); 406 setTimeout(function () { 407 marker.setAnimation(null); 408 }, 1700); 409 marker.setZIndex(google.maps.Marker.MAX_ZINDEX); 410 if (cis_options.autoZoomUp) { 411 self.zoomUpToBuildings(); 412 } 413 }; 414 415 this.addAutomaticMarker = function (address, saveCallback, readyCallback) { 416 if (!map) { 417 return; 418 } 419 420 self.searchAddress(address, 421 function (idx) { 422 var marker = markers[idx[0][0]]; 423 marker.setMap(map); 424 marker.setDraggable(true); 425 self.panToMarker(idx[0][0]); 426 if ("function" == typeof (saveCallback)) { 427 saveCallback(marker.getPosition().lat(), marker.getPosition().lng()); 428 } 429 addMarkerSaveCoordinatesListener(marker, saveCallback); 430 if ("function" == typeof (readyCallback)) { 431 readyCallback(arguments[1]); 432 } 433 }, 434 function () { 435 var mid = self.addMarker({ 436 lat: mapCenter[0], 437 lng: mapCenter[1], 438 draggable: true 439 }, automaticMarkerFaultText); 440 addMarkerSaveCoordinatesListener(markers[mid], saveCallback); 441 self.panToMarker(mid); 442 if ("function" == typeof (readyCallback)) { 443 readyCallback(arguments[0]); 444 } 445 }); 446 }; 447 448 //абÑолÑÑно одинаковÑй Ð´Ð»Ñ mapY и mapG меÑод 449 this.initAddresses = function (addressSpans, firstReadyCallback, addressClickHandler) { 450 if (!map) { 451 return; 452 } 453 if (!addressSpans) { 454 return; 455 } 456 var htmlDataMarkerInfo = 'markerinfo'; 457 var htmlDataAttrName = 'markerid'; 458 var htmlDataCleanAddress = 'addressinfo'; 459 var mapObjectIdx; 460 addressSpans.each(function (idx) { 461 var span = $(this); 462 var markerData = span.data(htmlDataMarkerInfo); 463 if (undefined != markerData) { 464 mapObjectIdx = self.addMarker(markerData); 465 span 466 .hide() 467 .after( 468 $(document.createElement('a')) 469 .attr('href', '#') 470 .addClass(span.attr('class')) 471 .html(span.html()) 472 .data(htmlDataAttrName, mapObjectIdx) 473 .click(function (evt) { 474 evt.preventDefault(); 475 self.panToMarker($(this).data(htmlDataAttrName)); 476 if ('function' == typeof (addressClickHandler)) { 477 addressClickHandler(); 478 } 479 }) 480 ) 481 .remove(); 482 if (idx == 0 && 'function' == typeof (firstReadyCallback)) { 483 firstReadyCallback(); 484 } 485 } else { 486 var valueToSearch; 487 if (span.data(htmlDataCleanAddress)) { 488 valueToSearch = span.data(htmlDataCleanAddress).cleanAddress; 489 } else { 490 valueToSearch = span.html(); 491 } 492 if (valueToSearch) { 493 self.searchAddress(valueToSearch, function (mapObjectIdx) { 494 wIdx = []; 495 jQuery.each(mapObjectIdx, function (key, value) { 496 wIdx.push(value[0]); 497 }); 498 span 499 .hide() 500 .after( 501 $(document.createElement('a')) 502 .attr('href', '#') 503 .addClass(span.attr('class')) 504 .html(span.html()) 505 .data(htmlDataAttrName, wIdx) 506 .click(function (evt) { 507 evt.preventDefault(); 508 self.panToWindow($(this).data(htmlDataAttrName)); 509 if ('function' == typeof (addressClickHandler)) { 510 addressClickHandler(); 511 } 512 }) 513 ) 514 .remove(); 515 if (idx == 0 && 'function' == typeof (firstReadyCallback)) { 516 firstReadyCallback(); 517 } 518 }); 519 } 520 } 521 }); 522 } 523 524 this.addAdminMarker = function (data, saveCallback) { 525 if (!map) return; 526 data.draggable = true; 527 var markerId = self.addMarker(data, data.title); 528 if (markerId != undefined) { 529 addMarkerSaveCoordinatesListener(markers[markerId], saveCallback); 530 return markerId; 531 } 532 return; 533 }; 534 535 this.triggerResize = function () { 536 if (!map) return; 537 google.maps.event.trigger(map, "resize"); 538 }; 539 540 this.zoomToPredefined = function (predefined) { 541 var center = map.getCenter(); 542 this.triggerResize(); 543 map.setZoom(getPredefinedZoomValue(predefined)); 544 map.setCenter(center); 545 } 546 547 this.showAllMarkersBounds = function () { 548 var maxLat = 0, minLat = 99999999999, maxLng = 0, minLng = 99999999999; 549 $.each(markers, function (key, value) { 550 var latlng = value.getPosition(); 551 if (latlng.lat() && latlng.lng()) { 552 maxLat = Math.max(maxLat, latlng.lat()); 553 maxLng = Math.max(maxLng, latlng.lng()); 554 minLat = Math.min(minLat, latlng.lat()); 555 minLng = Math.min(minLng, latlng.lng()); 556 } 557 }); 558 map.fitBounds(new google.maps.LatLngBounds(new google.maps.LatLng(maxLat, minLng), new google.maps.LatLng(minLat, maxLng))); 559 } 560 561 this.zoomUpToBuildings = function () { 562 if (map.getZoom() < cis_options.zoomBuildingsView) 563 map.setZoom(parseInt(cis_options.zoomBuildingsView)); 564 }; 565 566 Array.prototype.in_array = function (p_val) { 567 for (var i = 0, l = this.length; i < l; i++) { 568 if (this[i] == p_val) { 569 return true; 570 } 571 } 572 return false;
573 } 574 575 this.setOptions = function (userOptions) { 576 cis_options = userOptions || {}; 577 if (undefined == cis_options.razdel) { 578 cis_options.razdel = "map"; 579 } 580 if (undefined == cis_options.autoOpenMarkers) { 581 cis_options.autoOpenMarkers = true; 582 } 583 if (undefined == cis_options.autoZoomUp) { 584 cis_options.autoZoomUp = true; 585 } 586 if (undefined == cis_options.minZoom) { 587 cis_options.minZoom = zoomCityView; 588 } 589 if (undefined == cis_options.zoomBuildingsView) { 590 cis_options.zoomBuildingsView = 15; 591 } 592 cis_options.initZoom = getPredefinedZoomValue(cis_options.initZoom); 593 } 594 595 function getPredefinedZoomValue(predefined) { 596 if ('max' == predefined) { 597 return zoomCityView; 598 } else if ('min' == predefined) { 599 return cis_options.zoomBuildingsView; 600 } 601 return mapZoom; 602 } 603 604 this.addMetroMarker = function (data, saveCallback) { 605 metro_marker = new google.maps.Marker({ 606 isMetro: true, 607 draggable: data.draggable || false, 608 position: new google.maps.LatLng(data.lat, data.lng), 609 map: map, 610 icon: data.icon, 611 }); 612 markers.push(metro_marker); 613 if (undefined !== saveCallback) { 614 google.maps.event.addListener(metro_marker, "dragend", function (event) { 615 saveCallback(event.latLng.lat(), event.latLng.lng()); 616 }); 617 } 618 return markers.length - 1; 619 } 620 621 this.clearMetroMarker = function () { 622 markers.forEach(marker => { 623 if (marker.isMetro) { 624 marker.setMap(null); 625 } 626 }); 627 markers = markers.filter(marker => !marker.isMetro); 628 } 629 630 this.getNearSubway = function (callback) { 631 var request = { 632 location: markers[0].getPosition(), 633 radius: '1000', 634 type: 'subway_station', 635 rankby: google.maps.places.RankBy.DISTANCE 636 }; 637 var service = new google.maps.places.PlacesService(map); 638 service.nearbySearch(request, function (results, status) { 639 if (status == google.maps.places.PlacesServiceStatus.OK && results.length != 0) { 640 results.sort(function (a, b) { 641 var distanceToA = google.maps.geometry.spherical.computeDistanceBetween(markers[0].getPosition(), a.geometry.location); 642 var distanceToB = google.maps.geometry.spherical.computeDistanceBetween(markers[0].getPosition(), b.geometry.location); 643 if (distanceToA < distanceToB) { 644 return -1; 645 } else if (distanceToA > distanceToB) { 646 return 1; 647 } 648 return 0; 649 }); 650 651 var response = { 652 lat: results[0].geometry.location.lat(), 653 lng: results[0].geometry.location.lng(), 654 name: results[0].name 655 } 656 callback(response); 657 } else { 658 callback({error: true}); 659 } 660 }); 661 662 } 663 664 this.fitBoundsWithMarkers = function (marks, clickOnFirstMarker) { 665 if (0 === marks.length) { 666 return marks.length; 667 } 668 if (1 === marks.length) { 669 map.setCenter(marks[0].getPosition()); 670 self.zoomUpToBuildings(); 671 } else { 672 var latlngBounds = new google.maps.LatLngBounds(); 673 $.each(marks, function (i, el) { 674 latlngBounds.extend(el.getPosition()); 675 }); 676 map.fitBounds(latlngBounds); 677 } 678 if (clickOnFirstMarker) { 679 google.maps.event.trigger(marks[0], 'click'); 680 } 681 } 682 683}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.