var am = { version: '2.0', auther: 'jenuine', date: '2010-02-14', URL: { WEB: am_url_permalink, SCRIPT: am_url_aquamap, IMAGE: am_url_aquamap + '/image' }, ZOOM: { MIN: 4, WIDE: 10, INDIVIDUAL: 12, DETAIL: 14, MAX: 18 }, place: { regs: [], stations: [], serched: null }, zDigit: [ -1 , -2 , -1 , -1 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 2 , 2 , 2 , 3 , 3 , 4 , 4 , 5 , 5 ], // 0-19 // Google maps API map: null, markers: { reg: [], station: [] }, geocoder: null, directions: null, wayPoints: [], sv: { active: false, panorama: null, client: null, overlay: null, pegman: null }, current: { bounds: null, zoom: 0, reg: { data: { id: 0 } }, marker: null }, // Ext vp: {}, dialog: { isNewPlace: false }, store: { extractRegs: true }, reader: {}, template: {}, handler: {}, fx: { duration: 0.25 }, twitter: { channel: 0 } }; /* kind -------------------------------------------------------------------------------- */ am.getKindString = function(value){ switch (value) { case 1: return 'アクアショップ'; case 2: return 'ペットショップ'; case 3: return 'ホームセンター'; case 4: return '水族館'; case 5: return '展示水槽'; case 6: return 'イベント'; case 7: return '飲食店'; case 9: return 'その他'; }; }; am.getKindImage = function(value){ var path = am.URL.IMAGE + '/marker'; switch (value) { case 1: return path + '/blue-dot.png'; // アクアショップ case 2: return path + '/red-dot.png'; // ペットショップ case 3: return path + '/orange-dot.png'; // ホームセンター case 4: return path + '/ltblue-dot.png'; // 水族館 case 5: return path + '/purple-dot.png'; // 展示水槽 case 6: return path + '/pink-dot.png'; // イベント case 7: return path + '/green-dot.png'; // 飲食店 case 9: return path + '/yellow-dot.png'; // その他 case -1: return path + '/arrowGreen.png'; // 仮ポイント case -2: return path + '/arrowRed.png'; // 検索ポイント case -3: return path + '/rail.png'; // 最寄駅 }; }; am.getKindIcon = function(value){ var icon = new GIcon(); icon.image = am.getKindImage(value); var path = am.URL.IMAGE + '/marker'; if (value > 0) { icon.shadow = path + '/msmarker.shadow.png'; icon.iconSize = new GSize(32, 32); icon.shadowSize = new GSize(59, 32); icon.iconAnchor = new GPoint(15, 32); icon.infoWindowAnchor = new GPoint(16, 0); } else if (value >= -2) { icon.shadow = path + '/arrow.shadow.png'; icon.iconSize = new GSize(31, 28); icon.shadowSize = new GSize(46, 28); icon.iconAnchor = new GPoint(11, 28); icon.infoWindowAnchor = new GPoint(11, 0); } else if (value == -3) { icon.iconSize = new GSize(32, 32); icon.iconAnchor = new GPoint(11, 28); icon.infoWindowAnchor = new GPoint(16, 16); }; return icon; }; /** * @name MarkerClusterer * @version 1.0 * @author Xiaoxi Wu * @copyright (c) 2009 Xiaoxi Wu * @fileoverview * This javascript library creates and manages per-zoom-level * clusters for large amounts of markers (hundreds or thousands). * This library was inspired by the * Maptimize hosted clustering solution. *

* How it works:
* The MarkerClusterer will group markers into clusters according to * their distance from a cluster's center. When a marker is added, * the marker cluster will find a position in all the clusters, and * if it fails to find one, it will create a new cluster with the marker. * The number of markers in a cluster will be displayed * on the cluster marker. When the map viewport changes, * MarkerClusterer will destroy the clusters in the viewport * and regroup them into new clusters. * */ /* * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * @name MarkerClustererOptions * @class This class represents optional arguments to the {@link MarkerClusterer} * constructor. * @property {Number} [maxZoom] The max zoom level monitored by a * marker cluster. If not given, the marker cluster assumes the maximum map * zoom level. When maxZoom is reached or exceeded all markers will be shown * without cluster. * @property {Number} [gridSize=60] The grid size of a cluster in pixel. Each * cluster will be a square. If you want the algorithm to run faster, you can set * this value larger. * @property {Array of MarkerStyleOptions} [styles] * Custom styles for the cluster markers. * The array should be ordered according to increasing cluster size, * with the style for the smallest clusters first, and the style for the * largest clusters last. */ /** * @name MarkerStyleOptions * @class An array of these is passed into the {@link MarkerClustererOptions} * styles option. * @property {String} [url] Image url. * @property {Number} [height] Image height. * @property {Number} [height] Image width. * @property {Array of Number} [opt_anchor] Anchor for label text, like [24, 12]. * If not set, the text will align center and middle. * @property {String} [opt_textColor="black"] Text color. */ /** * Creates a new MarkerClusterer to cluster markers on the map. * * @constructor * @param {GMap2} map The map that the markers should be added to. * @param {Array of GMarker} opt_markers Initial set of markers to be clustered. * @param {MarkerClustererOptions} opt_opts A container for optional arguments. */ function MarkerClusterer(map, opt_markers, opt_opts) { // private members var clusters_ = []; var map_ = map; var maxZoom_ = null; var me_ = this; var gridSize_ = 60; var sizes = [53, 56, 66, 78, 90]; var styles_ = []; var leftMarkers_ = []; var mcfn_ = null; var i = 0; for (i = 1; i <= 5; ++i) { styles_.push({ //'url': "http://gmaps-utility-library.googlecode.com/svn/trunk/markerclusterer/images/m" + i + ".png", 'url': am.URL.IMAGE + '/clusterer/m' + i + '.png', 'height': sizes[i - 1], 'width': sizes[i - 1] }); } if (typeof opt_opts === "object" && opt_opts !== null) { if (typeof opt_opts.gridSize === "number" && opt_opts.gridSize > 0) { gridSize_ = opt_opts.gridSize; } if (typeof opt_opts.maxZoom === "number") { maxZoom_ = opt_opts.maxZoom; } if (typeof opt_opts.styles === "object" && opt_opts.styles !== null && opt_opts.styles.length !== 0) { styles_ = opt_opts.styles; } } /** * When we add a marker, the marker may not in the viewport of map, then we don't deal with it, instead * we add the marker into a array called leftMarkers_. When we reset MarkerClusterer we should add the * leftMarkers_ into MarkerClusterer. */ function addLeftMarkers_() { if (leftMarkers_.length === 0) { return; } var leftMarkers = []; for (i = 0; i < leftMarkers_.length; ++i) { me_.addMarker(leftMarkers_[i], true, null, null, true); } leftMarkers_ = leftMarkers; } /** * Get cluster marker images of this marker cluster. Mostly used by {@link Cluster} * @private * @return {Array of String} */ this.getStyles_ = function () { return styles_; }; /** * Remove all markers from MarkerClusterer. */ this.clearMarkers = function () { for (var i = 0; i < clusters_.length; ++i) { if (typeof clusters_[i] !== "undefined" && clusters_[i] !== null) { clusters_[i].clearMarkers(); } } clusters_ = []; leftMarkers_ = []; GEvent.removeListener(mcfn_); }; /** * Check a marker, whether it is in current map viewport. * @private * @return {Boolean} if it is in current map viewport */ function isMarkerInViewport_(marker) { return map_.getBounds().containsLatLng(marker.getLatLng()); } /** * When reset MarkerClusterer, there will be some markers get out of its cluster. * These markers should be add to new clusters. * @param {Array of GMarker} markers Markers to add. */ function reAddMarkers_(markers) { var len = markers.length; var clusters = []; for (var i = len - 1; i >= 0; --i) { me_.addMarker(markers[i].marker, true, markers[i].isAdded, clusters, true); } addLeftMarkers_(); } /** * Add a marker. * @private * @param {GMarker} marker Marker you want to add * @param {Boolean} opt_isNodraw Whether redraw the cluster contained the marker * @param {Boolean} opt_isAdded Whether the marker is added to map. Never use it. * @param {Array of Cluster} opt_clusters Provide a list of clusters, the marker * cluster will only check these cluster where the marker should join. */ this.addMarker = function (marker, opt_isNodraw, opt_isAdded, opt_clusters, opt_isNoCheck) { if (opt_isNoCheck !== true) { if (!isMarkerInViewport_(marker)) { leftMarkers_.push(marker); return; } } var isAdded = opt_isAdded; var clusters = opt_clusters; var pos = map_.fromLatLngToDivPixel(marker.getLatLng()); if (typeof isAdded !== "boolean") { isAdded = false; } if (typeof clusters !== "object" || clusters === null) { clusters = clusters_; } var length = clusters.length; var cluster = null; for (var i = length - 1; i >= 0; i--) { cluster = clusters[i]; var center = cluster.getCenter(); if (center === null) { continue; } center = map_.fromLatLngToDivPixel(center); // Found a cluster which contains the marker. if (pos.x >= center.x - gridSize_ && pos.x <= center.x + gridSize_ && pos.y >= center.y - gridSize_ && pos.y <= center.y + gridSize_) { cluster.addMarker({ 'isAdded': isAdded, 'marker': marker }); if (!opt_isNodraw) { cluster.redraw_(); } return; } } // No cluster contain the marker, create a new cluster. cluster = new Cluster(this, map); cluster.addMarker({ 'isAdded': isAdded, 'marker': marker }); if (!opt_isNodraw) { cluster.redraw_(); } // Add this cluster both in clusters provided and clusters_ clusters.push(cluster); if (clusters !== clusters_) { clusters_.push(cluster); } }; /** * Remove a marker. * * @param {GMarker} marker The marker you want to remove. */ this.removeMarker = function (marker) { for (var i = 0; i < clusters_.length; ++i) { if (clusters_[i].remove(marker)) { clusters_[i].redraw_(); return; } } }; /** * Redraw all clusters in viewport. */ this.redraw_ = function () { var clusters = this.getClustersInViewport_(); for (var i = 0; i < clusters.length; ++i) { clusters[i].redraw_(true); } }; /** * Get all clusters in viewport. * @return {Array of Cluster} */ this.getClustersInViewport_ = function () { var clusters = []; var curBounds = map_.getBounds(); for (var i = 0; i < clusters_.length; i ++) { if (clusters_[i].isInBounds(curBounds)) { clusters.push(clusters_[i]); } } return clusters; }; /** * Get max zoom level. * @private * @return {Number} */ this.getMaxZoom_ = function () { return maxZoom_; }; /** * Get map object. * @private * @return {GMap2} */ this.getMap_ = function () { return map_; }; /** * Get grid size * @private * @return {Number} */ this.getGridSize_ = function () { return gridSize_; }; /** * Get total number of markers. * @return {Number} */ this.getTotalMarkers = function () { var result = 0; for (var i = 0; i < clusters_.length; ++i) { result += clusters_[i].getTotalMarkers(); } return result; }; /** * Get total number of clusters. * @return {int} */ this.getTotalClusters = function () { return clusters_.length; }; /** * Collect all markers of clusters in viewport and regroup them. */ this.resetViewport = function () { var clusters = this.getClustersInViewport_(); var tmpMarkers = []; var removed = 0; for (var i = 0; i < clusters.length; ++i) { var cluster = clusters[i]; var oldZoom = cluster.getCurrentZoom(); if (oldZoom === null) { continue; } var curZoom = map_.getZoom(); if (curZoom !== oldZoom) { // If the cluster zoom level changed then destroy the cluster // and collect its markers. var mks = cluster.getMarkers(); for (var j = 0; j < mks.length; ++j) { var newMarker = { 'isAdded': false, 'marker': mks[j].marker }; tmpMarkers.push(newMarker); } cluster.clearMarkers(); removed++; for (j = 0; j < clusters_.length; ++j) { if (cluster === clusters_[j]) { clusters_.splice(j, 1); } } } } // Add the markers collected into marker cluster to reset reAddMarkers_(tmpMarkers); this.redraw_(); }; /** * Add a set of markers. * * @param {Array of GMarker} markers The markers you want to add. */ this.addMarkers = function (markers) { for (var i = 0; i < markers.length; ++i) { this.addMarker(markers[i], true); } this.redraw_(); }; // initialize if (typeof opt_markers === "object" && opt_markers !== null) { this.addMarkers(opt_markers); } // when map move end, regroup. mcfn_ = GEvent.addListener(map_, "moveend", function () { me_.resetViewport(); }); } /** * Create a cluster to collect markers. * A cluster includes some markers which are in a block of area. * If there are more than one markers in cluster, the cluster * will create a {@link ClusterMarker_} and show the total number * of markers in cluster. * * @constructor * @private * @param {MarkerClusterer} markerClusterer The marker cluster object */ function Cluster(markerClusterer) { var center_ = null; var markers_ = []; var markerClusterer_ = markerClusterer; var map_ = markerClusterer.getMap_(); var clusterMarker_ = null; var zoom_ = map_.getZoom(); /** * Get markers of this cluster. * * @return {Array of GMarker} */ this.getMarkers = function () { return markers_; }; /** * If this cluster intersects certain bounds. * * @param {GLatLngBounds} bounds A bounds to test * @return {Boolean} Is this cluster intersects the bounds */ this.isInBounds = function (bounds) { if (center_ === null) { return false; } if (!bounds) { bounds = map_.getBounds(); } var sw = map_.fromLatLngToDivPixel(bounds.getSouthWest()); var ne = map_.fromLatLngToDivPixel(bounds.getNorthEast()); var centerxy = map_.fromLatLngToDivPixel(center_); var inViewport = true; var gridSize = markerClusterer.getGridSize_(); if (zoom_ !== map_.getZoom()) { var dl = map_.getZoom() - zoom_; gridSize = Math.pow(2, dl) * gridSize; } if (ne.x !== sw.x && (centerxy.x + gridSize < sw.x || centerxy.x - gridSize > ne.x)) { inViewport = false; } if (inViewport && (centerxy.y + gridSize < ne.y || centerxy.y - gridSize > sw.y)) { inViewport = false; } return inViewport; }; /** * Get cluster center. * * @return {GLatLng} */ this.getCenter = function () { return center_; }; /** * Add a marker. * * @param {Object} marker An object of marker you want to add: * {Boolean} isAdded If the marker is added on map. * {GMarker} marker The marker you want to add. */ this.addMarker = function (marker) { if (center_ === null) { /*var pos = marker['marker'].getLatLng(); pos = map.fromLatLngToContainerPixel(pos); pos.x = parseInt(pos.x - pos.x % (GRIDWIDTH * 2) + GRIDWIDTH); pos.y = parseInt(pos.y - pos.y % (GRIDWIDTH * 2) + GRIDWIDTH); center = map.fromContainerPixelToLatLng(pos);*/ center_ = marker.marker.getLatLng(); } markers_.push(marker); }; /** * Remove a marker from cluster. * * @param {GMarker} marker The marker you want to remove. * @return {Boolean} Whether find the marker to be removed. */ this.removeMarker = function (marker) { for (var i = 0; i < markers_.length; ++i) { if (marker === markers_[i].marker) { if (markers_[i].isAdded) { map_.removeOverlay(markers_[i].marker); } markers_.splice(i, 1); return true; } } return false; }; /** * Get current zoom level of this cluster. * Note: the cluster zoom level and map zoom level not always the same. * * @return {Number} */ this.getCurrentZoom = function () { return zoom_; }; /** * Redraw a cluster. * @private * @param {Boolean} isForce If redraw by force, no matter if the cluster is * in viewport. */ this.redraw_ = function (isForce) { if (!isForce && !this.isInBounds()) { return; } // Set cluster zoom level. zoom_ = map_.getZoom(); var i = 0; var mz = markerClusterer.getMaxZoom_(); if (mz === null) { mz = map_.getCurrentMapType().getMaximumResolution(); } if (zoom_ >= mz || this.getTotalMarkers() === 1) { // If current zoom level is beyond the max zoom level or the cluster // have only one marker, the marker(s) in cluster will be showed on map. for (i = 0; i < markers_.length; ++i) { if (markers_[i].isAdded) { if (markers_[i].marker.isHidden()) { markers_[i].marker.show(); } } else { map_.addOverlay(markers_[i].marker); markers_[i].isAdded = true; } } if (clusterMarker_ !== null) { clusterMarker_.hide(); } } else { // Else add a cluster marker on map to show the number of markers in // this cluster. for (i = 0; i < markers_.length; ++i) { if (markers_[i].isAdded && (!markers_[i].marker.isHidden())) { markers_[i].marker.hide(); } } if (clusterMarker_ === null) { clusterMarker_ = new ClusterMarker_(center_, this.getTotalMarkers(), markerClusterer_.getStyles_(), markerClusterer_.getGridSize_()); map_.addOverlay(clusterMarker_); } else { if (clusterMarker_.isHidden()) { clusterMarker_.show(); } clusterMarker_.redraw(true); } } }; /** * Remove all the markers from this cluster. */ this.clearMarkers = function () { if (clusterMarker_ !== null) { map_.removeOverlay(clusterMarker_); } for (var i = 0; i < markers_.length; ++i) { if (markers_[i].isAdded) { map_.removeOverlay(markers_[i].marker); } } markers_ = []; }; /** * Get number of markers. * @return {Number} */ this.getTotalMarkers = function () { return markers_.length; }; } /** * ClusterMarker_ creates a marker that shows the number of markers that * a cluster contains. * * @constructor * @private * @param {GLatLng} latlng Marker's lat and lng. * @param {Number} count Number to show. * @param {Array of Object} styles The image list to be showed: * {String} url Image url. * {Number} height Image height. * {Number} width Image width. * {Array of Number} anchor Text anchor of image left and top. * {String} textColor text color. * @param {Number} padding Padding of marker center. */ function ClusterMarker_(latlng, count, styles, padding) { var index = 0; var dv = count; while (dv !== 0) { dv = parseInt(dv / 10, 10); index ++; } if (styles.length < index) { index = styles.length; } this.url_ = styles[index - 1].url; this.height_ = styles[index - 1].height; this.width_ = styles[index - 1].width; this.textColor_ = styles[index - 1].opt_textColor; this.anchor_ = styles[index - 1].opt_anchor; this.latlng_ = latlng; this.index_ = index; this.styles_ = styles; this.text_ = count; this.padding_ = padding; } ClusterMarker_.prototype = new GOverlay(); /** * Initialize cluster marker. * @private */ ClusterMarker_.prototype.initialize = function (map) { this.map_ = map; var div = document.createElement("div"); var latlng = this.latlng_; var pos = map.fromLatLngToDivPixel(latlng); pos.x -= parseInt(this.width_ / 2, 10); pos.y -= parseInt(this.height_ / 2, 10); var mstyle = ""; if (document.all) { mstyle = 'filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale,src="' + this.url_ + '");'; } else { mstyle = "background:url(" + this.url_ + ");"; } if (typeof this.anchor_ === "object") { if (typeof this.anchor_[0] === "number" && this.anchor_[0] > 0 && this.anchor_[0] < this.height_) { mstyle += 'height:' + (this.height_ - this.anchor_[0]) + 'px;padding-top:' + this.anchor_[0] + 'px;'; } else { mstyle += 'height:' + this.height_ + 'px;line-height:' + this.height_ + 'px;'; } if (typeof this.anchor_[1] === "number" && this.anchor_[1] > 0 && this.anchor_[1] < this.width_) { mstyle += 'width:' + (this.width_ - this.anchor_[1]) + 'px;padding-left:' + this.anchor_[1] + 'px;'; } else { mstyle += 'width:' + this.width_ + 'px;text-align:center;'; } } else { mstyle += 'height:' + this.height_ + 'px;line-height:' + this.height_ + 'px;'; mstyle += 'width:' + this.width_ + 'px;text-align:center;'; } var txtColor = this.textColor_ ? this.textColor_ : 'black'; div.style.cssText = mstyle + 'cursor:pointer;top:' + pos.y + "px;left:" + pos.x + "px;color:" + txtColor + ";position:absolute;font-size:11px;" + 'font-family:Arial,sans-serif;font-weight:bold'; div.innerHTML = this.text_; map.getPane(G_MAP_MAP_PANE).appendChild(div); var padding = this.padding_; GEvent.addDomListener(div, "click", function () { var pos = map.fromLatLngToDivPixel(latlng); var sw = new GPoint(pos.x - padding, pos.y + padding); sw = map.fromDivPixelToLatLng(sw); var ne = new GPoint(pos.x + padding, pos.y - padding); ne = map.fromDivPixelToLatLng(ne); var zoom = map.getBoundsZoomLevel(new GLatLngBounds(sw, ne), map.getSize()); map.setCenter(latlng, zoom); }); this.div_ = div; }; /** * Remove this overlay. * @private */ ClusterMarker_.prototype.remove = function () { this.div_.parentNode.removeChild(this.div_); }; /** * Copy this overlay. * @private */ ClusterMarker_.prototype.copy = function () { return new ClusterMarker_(this.latlng_, this.index_, this.text_, this.styles_, this.padding_); }; /** * Redraw this overlay. * @private */ ClusterMarker_.prototype.redraw = function (force) { if (!force) { return; } var pos = this.map_.fromLatLngToDivPixel(this.latlng_); pos.x -= parseInt(this.width_ / 2, 10); pos.y -= parseInt(this.height_ / 2, 10); this.div_.style.top = pos.y + "px"; this.div_.style.left = pos.x + "px"; }; /** * Hide this cluster marker. */ ClusterMarker_.prototype.hide = function () { this.div_.style.display = "none"; }; /** * Show this cluster marker. */ ClusterMarker_.prototype.show = function () { this.div_.style.display = ""; }; /** * Get whether the cluster marker is hidden. * @return {Boolean} */ ClusterMarker_.prototype.isHidden = function () { return this.div_.style.display === "none"; }; am.Place = function(data, draggable){ this.data = data; var options = {}; options.icon = am.getKindIcon(data.kind); options.title = data.title; if (draggable) options.draggable = true; this.marker = new GMarker(this.data.latlng , options); this.marker.id = data.id; var self = this; GEvent.addListener(self.marker, 'click', function() { self.click(); }); }; am.Place.prototype.visibleZoom = am.ZOOM.INDIVIDUAL; am.Place.prototype.click = function() { var doOpenInfo = true; if (am.current.marker != this.marker) { if (this.data.kind > 0) { am.vp.pnlReg.activate(); if (am.current.reg.data.id != this.data.id) { am.loadAttribute(this.data.id, function(){ am.vp.pnlReg.scrollTo('#streetview'); }); am.loadStation(this.data.lat, this.data.lng); am.loadComment(this.data.id); if (am.sv.active) am.sv.show(this.data.latlng); }; am.current.reg = this; }; if (this.data.kind == -3) { GEvent.clearListeners(am.directions, 'load'); var self = this; GEvent.addListener(am.directions, 'load', function(){ self.data.routeSummary = am.directions.getSummaryHtml(); self.openInfo(); }); am.wayPoints = [this.data.latlng, am.current.reg.data.latlng]; am.directions.loadFromWaypoints(am.wayPoints, { locale: 'ja_JP', travelMode: G_TRAVEL_MODE_WALKING,//G_TRAVEL_MODE_DRIVING preserveViewport: true }); doOpenInfo = false; } else { am.directions.clear(); }; am.current.marker = this.marker; }; if (doOpenInfo) this.openInfo(); }; am.Place.prototype.openInfo = function() { var html = '
'; // 登録ポイント if (this.data.kind > 0) { html += '
'; html += '' + am.getKindString(this.data.kind) + ''; html += '

' + this.data.title + '

'; if (this.data.withed) { html += ''; }; html += '
'; } // 仮ポイント else if (this.data.kind == -1){ html += '
'; html += '

' + this.data.title + '

'; html += '
'; } // 検索ポイント else if (this.data.kind == -2){ html += '
'; html += '住所検索結果'; html += '

' + this.data.title + '

'; html += '
'; } // 最寄駅 else if (this.data.kind == -3){ html += '
'; html += '

' + this.data.title + '

'; var s = '-'; if (this.data.prev) s = this.data.prev + '駅'; if (this.data.next) { if (s) s += ', '; s += this.data.next + '駅'; } html += ''; html += '
'; html += am.current.reg.data.title + 'まで'; html += '
    '; html += '
  • 直線距離: ' + this.data.distance + '
  • '; html += '
  • 徒歩ルート: ' + this.data.routeSummary + '
  • '; html += '
'; html += '
'; html += '
'; }; html += this.getWizardHtml(); html += '
'; this.marker.openInfoWindowHtml(html); }; am.Place.prototype.getWizardHtml = function(){ var html = '
'; html += 'ズーム'; //html += 'twitter検索'; if (this.data.kind >0) { // } else if (this.data.kind == -2) { html += '新規登録'; } else if (this.data.kind == -3) { //html += '徒歩ルートを表示'; }; html += '
'; return html; }; am.Place.prototype.show = function(){ if (am.current.zoom < this.visibleZoom) am.map.setCenter(this.data.latlng, this.visibleZoom); else if (!am.current.bounds.containsLatLng(this.data.latlng)) am.map.panTo(this.data.latlng); }; /* Reader -------------------------------------------------------------------------------- */ am.reader.reg = new Ext.data.XmlReader({ record: 'place' }, [ {name: 'id', type: 'int'}, {name: 'title'}, {name: 'address'}, {name: 'lat', type: 'float'}, {name: 'lng', type: 'float'}, {name: 'kind', type: 'int'}, {name: 'withed', type: 'boolean'}, {name: 'withFish', type: 'boolean'}, {name: 'withSwFish', type: 'boolean'}, {name: 'withGoldfish', type: 'boolean'}, {name: 'withShrimp', type: 'boolean'}, {name: 'withWeeds', type: 'boolean'}, {name: 'withADA', type: 'boolean'}, {name: 'withDoaqua', type: 'boolean'}, {name: 'comCount', type: 'int'} ]); am.reader.attribute = new Ext.data.XmlReader({ record: 'place' }, [ {name: 'id', type: 'int'}, {name: 'title'}, {name: 'lat', type: 'float'}, {name: 'lng', type: 'float'}, {name: 'kind', type: 'int'}, {name: 'withed', type: 'boolean'}, {name: 'withFish', type: 'boolean'}, {name: 'withSwFish', type: 'boolean'}, {name: 'withGoldfish', type: 'boolean'}, {name: 'withShrimp', type: 'boolean'}, {name: 'withWeeds', type: 'boolean'}, {name: 'withADA', type: 'boolean'}, {name: 'withDoaqua', type: 'boolean'}, {name: 'address'}, //{name: 'pref'}, //{name: 'zip'}, {name: 'tel'}, {name: 'fax'}, {name: 'hours'}, {name: 'holiday'}, {name: 'parking'}, {name: 'fee'}, {name: 'url'}, {name: 'description'}, {name: 'date'} ]); am.reader.comment = new Ext.data.XmlReader({ record: 'comment' }, [ {name: 'id', type: 'int'}, {name: 'name'}, {name: 'url'}, {name: 'commentText'}, {name: 'date'} ]); am.reader.rReg = new Ext.data.XmlReader({ record: 'place' }, [ {name: 'id', type: 'int'}, {name: 'title'}, {name: 'date'} ]); am.reader.rComment = new Ext.data.XmlReader({ record: 'comment' }, [ {name: 'id', type: 'int'}, {name: 'title'}, {name: 'name'}, {name: 'url'}, {name: 'commentText'}, {name: 'date'} ]); am.reader.station = new Ext.data.JsonReader({ root: 'response.station', fields: [ {name: 'name'}, // 最寄駅名 {name: 'prev'}, // 前の駅名 (始発駅の場合は null) {name: 'next'}, // 次の駅名 (終着駅の場合は null) {name: 'x'}, // 最寄駅の経度 (世界測地系) {name: 'y'}, // 最寄駅の緯度 (世界測地系) {name: 'distance'}, // 指定の場所から最寄駅までの距離 (精度は 10 m) {name: 'postal'}, // 最寄駅の郵便番号 {name: 'prefecture'}, // 最寄駅の存在する都道府県名 {name: 'line'} // 最寄駅の存在する路線名 ] }); am.reader.serched = new Ext.data.JsonReader({ root: 'Placemark', fields: [ {name: 'id', mapping: 'id'}, {name: 'address', mapping: 'address'}, {name: 'addressDetails', mapping: 'AddressDetails'}, {name: 'point', mapping: 'Point'}, {name: 'lat', mapping: 'Point.coordinates[1]'}, {name: 'lng', mapping: 'Point.coordinates[0]'} ] }); /* twitter */ am.reader.twitterSearch = new Ext.data.JsonReader({ root: 'results', fields: [ {name: 'user', mapping: 'from_user'}, {name: 'image', mapping: 'profile_image_url'}, {name: 'time', mapping: 'created_at'}, {name: 'text'}, {name: 'source'}, ] }); /* sample "location":"New York, NY", "profile_image_url":"http://a3.twimg.com/profile_images/637816643/blogging-avatar-square-2_normal.jpg", "created_at":"Tue, 23 Feb 2010 10:55:04 +0000", "from_user":"BloggingBlog", "to_user_id":null, "text":"New Blog Pls RT: Blog Style Guide? Blog Editorial Guidelines? Blog Huh?... http://bit.ly/9yGGwv", "id":9520972172, "from_user_id":91047521, "geo":null, "iso_language_code":"nl", "source":"<a href="http://apiwiki.twitter.com/" rel="nofollow">API</a>" */ /* Store -------------------------------------------------------------------------------- */ am.store.regs = new Ext.data.Store({ proxy: new Ext.data.HttpProxy({ url: am.URL.SCRIPT + '/place.php', method: 'GET' }), reader: am.reader.reg, sortInfo: { field: 'address', direction: 'DESC' }, autoDestroy: true }); /* for update */ am.store.reg = new Ext.data.Store({ proxy: new Ext.data.HttpProxy({ url: am.URL.SCRIPT + '/place.php', method: 'GET' }), reader: am.reader.reg }); am.store.attribute = new Ext.data.Store({ proxy: new Ext.data.HttpProxy({ url: am.URL.SCRIPT + '/place.php', method: 'GET' }), baseParams: {c: 1}, reader: am.reader.attribute, autoDestroy: true }); am.store.comments = new Ext.data.Store({ proxy: new Ext.data.HttpProxy({ url: am.URL.SCRIPT + '/comment.php', method: 'GET' }), reader: am.reader.comment, autoDestroy: true }); am.store.rReg = new Ext.data.Store({ proxy: new Ext.data.HttpProxy({ url: am.URL.SCRIPT + '/recent.php', method: 'GET' }), baseParams: {t: 0}, reader: am.reader.rReg, autoDestroy: true }); am.store.rComment = new Ext.data.Store({ proxy: new Ext.data.HttpProxy({ url: am.URL.SCRIPT + '/recent.php', method: 'GET' }), baseParams: {t: 1}, reader: am.reader.rComment, autoDestroy: true }); am.store.stations = new Ext.data.Store({ proxy: new Ext.data.ScriptTagProxy({ url: 'http://express.heartrails.com/api/json', method: 'GET' }), baseParams: { method: 'getStations' }, reader: am.reader.station, autoDestroy: true }); am.store.serched = new Ext.data.Store({ proxy: new Ext.data.ScriptTagProxy({ url: 'http://maps.google.co.jp/maps/geo' }), baseParams: { output: 'json', oe: 'utf-8', key: am_gmapKey }, reader: am.reader.serched, autoDestroy: true }); /* twitter */ am.store.twitterSearch = new Ext.data.Store({ proxy: new Ext.data.ScriptTagProxy({ url: 'http://search.twitter.com/search.json' }), baseParams: { lang: 'ja', rpp: 100 }, reader: am.reader.twitterSearch, autoDestroy: true }); /* template -------------------------------------------------------------------------------- */ am.template.attribute = new Ext.XTemplate( '
', '', '

{title}

', '
', '{[am.getKindString(values.kind)]}', 'map', 'Last Modified: {date}', '
', '
', '
住所:
{address}
', '
電話番号:
{tel}
', '
FAX番号:
{fax}
', '
WEB:
{url}
', /* '
種類
', 'アクアショップ', 'ペットショップ', 'ホームセンター', '水族館', '展示水槽', 'イベント', 'その他', '
', */ '
取扱い:
    ', '
  • ADA
  • ', '
  • Do!aqua
  • ', '
  • 淡水魚
  • ', '
  • 海水魚
  • ', '
  • 金魚
  • ', '
  • CRS
  • ', '
  • 水草
  • ', '
', '
営業時間:
{hours}
', '
定休日:
{holiday}
', '
駐車場:
{parking}
', '
料金:
{fee}
', '
その他:
{description}
', '
', '
', '
' ); am.template.stations = new Ext.XTemplate( /* '
', '

最寄り駅

', '', '
' */ '
', '
', '
最寄り駅:
', '
    ', '', '
  • {name}駅 - {line}, {distance}
  • ', '
    ', '
', '
', '
', '
' ); am.template.stations_empty = '
' + '
' + '
最寄り駅:
' + '
    ' + '
  • 最寄りはありません
  • ' + '
' + '
' + '
' + '
'; am.template.comments = new Ext.XTemplate( '
', '

クチコミ

', '', '
' ); am.template.comments_empty = '
' + '

クチコミ

' + '' + '
'; am.template.rReg = new Ext.XTemplate( '
', '

最近の登録・編集された場所

', '', '
' ); am.template.rComment = new Ext.XTemplate( '
', '

最近のクチコミ

', '', '
' ); am.template.serched = new Ext.XTemplate( '', '
', '{[am.getAddrString(values.address)]}', '
', '
' ); /* twitter */ am.template.twitterSearch = new Ext.XTemplate( '
', //'

Twitter検索 (テスト中)

', //'

{[am.current.place.data.title]} の周辺でのつぶやき

', '', '
' ); /* am.template.twitterSearch_geocode_empty = '
', '

Twitter検索 (テスト中)

', '

{[am.current.place.data.title]} の周辺でのつぶやき

', '', '
'; *//* map -------------------------------------------------------------------------------- */ am.createMap = function(){ this.map = new GMap2(Ext.getDom('mapCanvas')); this.map.setCenter(new GLatLng(am_initial_lat, am_initial_lng), Math.max(am_initial_zoom, this.ZOOM.MIN)); this.map.addControl(new GLargeMapControl3D()); this.map.addControl(new GOverviewMapControl()); this.map.enableScrollWheelZoom(); this.map.enableContinuousZoom(); this.current.bounds = this.map.getBounds(); this.current.zoom = this.map.getZoom(); $('#mapCanvas').append('
'); $('#ds').append('
'); $('#ds').append('
'); //GEvent.addListener(this.map, 'movestart', function(){}); GEvent.addListener(this.map, 'moveend', function(){ am.current.bounds = am.map.getBounds(); am.current.zoom = am.map.getZoom(); am.filterRegs(); }); GEvent.addListener(this.map, 'zoomend', function(oldLevel, newLevel){ am.current.zoom = am.map.getZoom(); am.plot(am.place.stations, am.ZOOM.DETAIL); }); GEvent.addListener(this.map, 'click', function(overlay, latlng, overlaylatlng){ if (!overlay) { //am.map.closeInfoWindow(); var button = Ext.getCmp('btnSetMarker'); if (button.pressed) { if (am.place.serched) am.map.removeOverlay(am.place.serched.marker); var data ={}; data.id = 0; data.kind = -2; data.lat = latlng.lat(); data.lng = latlng.lng(); data.latlng = new GLatLng(data.lat, data.lng); am.geocoder.getLocations(data.latlng, function(locations) { if (locations.Status.code == G_GEO_SUCCESS) data.title = am.getAddrString(locations.Placemark[0].address); else data.title = '不明'; am.place.serched = new am.Place(data); am.map.addOverlay(am.place.serched.marker); am.place.serched.click(); }); am.serch.geo.combo.setValue(''); Ext.getCmp('btnClearSerched').enable(); button.toggle(false); Ext.get('mapCanvas').removeClass('curArrow'); }; }; }); this.geocoder = new GClientGeocoder(); this.directions = new GDirections(am.map, Ext.getDom('route')); GEvent.addListener(this.directions, 'addoverlay', function (){ for (var i=0, n=am.wayPoints.length; i 0) { $('#pnlReg .sideBody').scrollTo('#streetview', 100, { easing: 'swing', onAfter: function(){ f.async(null, [latlng]); } }); } else { f.async(null, [latlng]); }; }); }; return this.show(latlng); }; am.sv.hide = function(callback){ if (this.pegman) am.map.removeOverlay(this.pegman); if (this.overlay) am.map.removeOverlay(this.overlay); if (!this.panorama.isHidden()) this.panorama.hide(); var el = null; if (Ext.fly('panoramaMes').isDisplayed()) el = Ext.fly('panoramaMes'); else if (Ext.fly('panoramaCanvas').isDisplayed()) el = Ext.fly('panoramaCanvas'); if (el) { el.slideOut('t', { remove: false, useDisplay: true, duration: am.fx.duration*2, callback: function(){ if (callback) callback(); } }); } else { if (callback) callback(); }; }; /* data -------------------------------------------------------------------------------- */ am.loadRegs = function(callback){ am.store.regs.load({ callback: function(r, options, success){ if (success) { am.clearPlace(am.place.regs); var store = am.store.regs; for (var i=0, n=store.getCount(); i= am.ZOOM.WIDE) { if (am.current.bounds.containsLatLng(record.get('latlng'))) return true; } }; }); if (callback) callback(); }, callback, id); am.filterRegs = function(callback){ f.async(null, [callback]); }; return am.filterRegs(callback); }; am.filterRegsWith = function(id){ am.store.regs.filterBy(function(record){ if (record.get('id') == id) return true; else if (am.store.extractRegs) { if (am.current.zoom >= am.ZOOM.WIDE) { if (am.current.bounds.containsLatLng(record.get('latlng'))) return true; } }; }); }; am.updateRegs = function(id, updateMarker){ am.store.reg.baseParams.id = id; am.store.reg.load({ callback: function(r, options, success){ if (success) { am.filterRegsWith(id); var record = r[0]; var latlng = new GLatLng(record.get('lat'), record.get('lng')); record.set('latlng', latlng); var regs = am.store.regs; var state = regs.getSortState(); var index = regs.find('id', id); if (index >= 0) { regs.removeAt(index); regs.insert(index, record); } else { regs.insert(0, record); }; regs.sort(state.field, state.direction); if (!updateMarker) { am.place.regs[id].openInfo(); } else { am.updateMarkers(record.data); }; } else { am.vp.grdRegs.hide(); $('#nav').html('

致命的エラーが発生しました!

'); }; } }); }; am.updateMarkers = function(data){ var loadStation = false; if ((!am.dialog.isNewPlace) && (am.place.regs[data.id].data.latlng.toString() != data.latlng.toString())) loadStation = true; am.place.regs[data.id] = new am.Place(data); //if ((am.dialog.isNewPlace) || (am.place.regs[data.id].data.kind != data.kind) || (am.place.regs[data.id].data.latlng.toString() != data.latlng.toString())) { am.markers.reg.length = 0; for (var i=0, n=am.place.regs.length; i= zoom) { for (var i=0, n=places.length; i$1'); // ハッシュタグ text = text.replace(/(\s*)(\#)([a-z0-9]*)([\s\r]*)/gi, '$1$2$3$4'); // @ text = text.replace(/(@)([0-9a-z_]{1,15})/gi, '$1$2'); return text; }; am.unescapeEntities = function(value) { function unescape(char) { var str = null; if (char == '&') str = '&'; else if (char == '>') str = '>'; else if (char == '<') str = '<'; else if (char == '"') str = '"'; else if (char == ''') str = "'"; else str = ''; return str; }; return value.replace(/&|>|<|"|'/g, unescape); }; am.twitterSearch = function(channel){ Ext.getCmp('tpSidebar').activate('pnlTwitter'); Ext.getCmp('tpSidebar').activate('pnlTwitter'); Ext.get('twitterSearchTitle').fadeOut(); var el = Ext.get('dvTwitter'); el.fadeOut({ remove: false, //useDisplay: true, duration: am.fx.duration, callback: function(){ if (!channel) channel = 1; var key = []; var ng = []; var pMeta = ''; switch (channel) { case 1: pMeta = 'aquamap (テスト中)'; key.push('aquamap'); key.push('#aquamap'); break; case 2: pMeta = 'アクアリム全般'; key.push('aquarium'); key.push('aquamap'); key.push('テラリウム'); key.push('水槽'); key.push('熱帯魚'); key.push('金魚'); key.push('コリドラス'); key.push('水草'); key.push('ADA'); key.push('水族'); break; case 3: pMeta = 'Nature Aquarium (テスト中)'; key.push('aquarium'); key.push('ADA'); key.push('水草'); key.push('水草レイアウト'); break; case 11: pMeta = 'Hash Tag of #aquarium, #aquariumJP'; key.push('#aquarium'); key.push('#aquariumJP'); break; case 99: pMeta = 'テスト中 ...'; key.push('aquarium'); key.push('ADA'); key.push('水草'); key.push('キューブガーデン'); key.push('ネイチャーアクアリウム'); key.push('ソイル'); key.push('化粧砂'); key.push('流木'); key.push('トリミング'); break; }; /* var key = []; key.push('aquarium'); key.push('aquamap'); key.push('アクア'); key.push('テラリウム'); key.push('水槽'); //key.push('魚'); //key.push('さかな'); key.push('熱帯魚'); //key.push('海水魚'); key.push('金魚'); //key.push('メダカ'); //key.push('古代魚'); key.push('コリドラス'); //key.push('CRS'); key.push('水草'); key.push('水族'); //ng.push('魚座'); */ var ngStr = ''; for (var i=0, n=ng.length; i'; Ext.get('twitterSearchTitle').update(html); Ext.get('twitterSearchTitle').fadeIn(); $('#pnlTwitter .sideBody').scrollTo('#twitterSearchTitle', 500, { easing: 'swing', onAfter: function(){ el.fadeIn({ duration: am.fx.duration }); } }); am.twitter.channel = channel; } else { el.dom.innerHTML = '

エラー: twitterとの通信に失敗しました。

'; el.show(); }; } }); } }); }; /* am.twitterSearch_geocode = function(){ Ext.getCmp('tpSidebar').activate('pnlTwitter'); var el = Ext.get('dvTwitter'); el.fadeOut({ remove: false, //useDisplay: true, duration: am2.fx.duration, callback: function(){ var latlng = am2.current.marker.getLatLng(); var lat = latlng.lat(); var lng = latlng.lng(); am2.store.twitter_geocode.baseParams.geocode = lat + ',' + lng + ',1km'; am2.store.twitter_geocode.load({ callback: function(r, options, success){ if (success) { $('#pnlTwitter .sideBody').scrollTo('#dvTwitter', 500, { easing: 'swing', onAfter: function(){ el.fadeIn({ duration: am2.fx.duration }); } }); } else { el.dom.innerHTML = '

エラー: twitterとの通信に失敗しました。

'; el.show(); }; } }); } }); }; */ am.handler.changeMaptype = function(){ if (am.map.getCurrentMapType() != this.mt) { am.map.setMapType(this.mt); //am.ZOOM.MAX = this.mt.getMaximumResolution(); } else { this.toggle(true); }; }; am.vp.toolbar = new Ext.Toolbar({ cls: 'toolbar', items: [' ', { text: '地図', //iconCls: 'icoMap', enableToggle: true, toggleGroup: 'mapType', pressed: true, mt: G_NORMAL_MAP, handler: am.handler.changeMaptype }, { text: '航空写真', //iconCls: 'icoMap', enableToggle: true, toggleGroup: 'mapType', mt: G_SATELLITE_MAP, handler: am.handler.changeMaptype }, { text: '地図+写真', //iconCls: 'icoMap', enableToggle: true, toggleGroup: 'mapType', mt: G_HYBRID_MAP, handler: am.handler.changeMaptype }, { text: '地形', //iconCls: 'icoMap', enableToggle: true, toggleGroup: 'mapType', mt: G_PHYSICAL_MAP, handler: am.handler.changeMaptype }, '-', { xtype: 'panel', border: false, html: '' }, ' ', { iconCls: 'icoArrowRed', tooltip: 'マークする', id: 'btnSetMarker', enableToggle: true, handler: function(){ if (this.pressed) { Ext.get('mapCanvas').addClass('curArrow'); } else { Ext.get('mapCanvas').removeClass('curArrow'); }; } }, { iconCls: 'icoCancel', tooltip: 'マーカーをクリア', id: 'btnClearSerched', disabled: true, handler: function(){ if (am.place.serched) am.map.removeOverlay(am.place.serched.marker); am.serch.geo.combo.setValue(''); this.disable(); } }, '-', { text: 'リスト', id: 'btnToggleNav', iconCls: 'icoNav', enableToggle: true, pressed: true, handler: function(){ if (this.pressed) { Ext.getCmp('nav').expand(); } else { Ext.getCmp('nav').collapse(); } } }, ' ', { text: 'リンク', id: 'btnLink', iconCls: 'icoLink', handler: function(){ am.showLink(); } }] }); am.handler.render = { kind: function(value){ return am.getKindString(value); }, comment: function(value){ if (value > 0) return value+' 件 '; }, tick: { blue: function(value){ if (value) return ''; }, green: function(value){ if (value) return ''; } } }; am.vp.cmRegs = new Ext.grid.ColumnModel({ defaults: { sortable: true }, columns: [ //{header: 'ID', dataIndex: 'id', width: 30}, //{header: '緯度', dataIndex: 'lat', width: 40}, //{header: '経度', dataIndex: 'lng', width: 40}, {header: '種類', dataIndex: 'kind', width: 80, renderer: am.handler.render.kind}, {header: '名称', dataIndex: 'title', width: 180}, {header: '住所', dataIndex: 'address', width: 300, id: 'colAddress'}, {header: 'クチコミ', dataIndex: 'comCount', width: 50, align: 'right', renderer: am.handler.render.comment}, {header: 'ADA', dataIndex: 'withADA', width: 34, align: 'center', renderer: am.handler.render.tick.blue}, {header: 'Do!', dataIndex: 'withDoaqua', width: 34, align: 'center', renderer: am.handler.render.tick.blue}, {header: '淡水', dataIndex: 'withFish', width: 34, align: 'center', renderer: am.handler.render.tick.green}, {header: '海水', dataIndex: 'withSwFish', width: 34, align: 'center', renderer: am.handler.render.tick.green}, {header: '金魚', dataIndex: 'withGoldfish', width: 34, align: 'center', renderer: am.handler.render.tick.green}, {header: 'CRS', dataIndex: 'withShrimp', width: 34, align: 'center', renderer: am.handler.render.tick.green}, {header: '水草', dataIndex: 'withWeeds', width: 34, align: 'center', renderer: am.handler.render.tick.green} ] }); am.vp.grdRegs = new Ext.grid.GridPanel({ id: 'grdRegs', store: am.store.regs, colModel: am.vp.cmRegs, stripeRows: true, autoExpandColumn: 'colAddress', loadMask: false, viewConfig: { emptyText: '

このエリアには登録場所がないか、
もしくはズームレベルが低いためリストを表示できません。
※ズームレベルが' + am.ZOOM.WIDE + '以上でリストを表示します。

' }, sm: new Ext.grid.RowSelectionModel({ singleSelect: true, listeners: { rowselect: { fn: function(sm, index, record){ this.clearSelections(); am.place.regs[record.data.id].show(); am.place.regs[record.data.id].click(); } } } }) }); am.vp.pnlHome = { title: 'ホーム', id: 'pnlHome', iconCls: 'icoHome', defaults: {border: false}, items: [{ cls: 'sideItems', defaults: { border: false, cls: 'section' }, items: [{ contentEl: 'welcome' }, { contentEl: 'announceWithTwitter' }, { xtype: 'dataview', id: 'dvRReg', store: am.store.rReg, tpl: am.template.rReg, emptyText: '

最近登録・編集された場所はありません。

', itemSelector: 'li' }, { xtype: 'dataview', id: 'dvRComment', store: am.store.rComment, tpl: am.template.rComment, emptyText: '

最近投稿されたクチコミはありません。

', itemSelector: 'li' }, { cls: '', html: '
' }] }, { html: '

aquamap2

' }], listeners: { show: function(){ am.store.rReg.load(); am.store.rComment.load(); } } }; am.vp.pnlReg = { title: '詳細', id: 'pnlReg', iconCls: 'icoReg', defaults: {border: false}, disabled: true, tbar:{ items: [{ text: 'StreetView', id: 'btnStreetview', iconCls: 'icoStreetview', enableToggle: true, handler: function(){ am.sv.active = this.pressed; if (am.sv.active) am.sv.show(am.current.reg.data.latlng); else am.sv.hide(); } }, '-', { text: '編集', id: 'btnEditAttribute', iconCls: 'icoEditAttr', handler: function(){ am.postPlace(); } }, { text: 'クチコミを投稿', id: 'btnPostComment', iconCls: 'icoAddComment', handler: function(){ am.postComment(); } }] }, items: [{ cls: 'sideItems', defaults: { border: false }, items: [{ id: 'streetview', html: '
' }, { xtype: 'dataview', id: 'dvAttribute', store: am.store.attribute, tpl: am.template.attribute, itemSelector: 'div.attribute' }, { xtype: 'dataview', id: 'dvStations', store: am.store.stations, tpl: am.template.stations, emptyText: am.template.stations_empty, itemSelector: 'li' }, { xtype: 'dataview', id: 'dvComment', store: am.store.comments, tpl: am.template.comments, emptyText: am.template.comments_empty, itemSelector: 'li' }, { html: '
' }] }, { html: '

aquamap2

' }], listeners: { bodyresize: function(p, width, height){ /* if (am2.sv.mode) { if (am2.sv.panorama) { am2.sv.panorama.checkResize(); }; }; */ } } };am.vp.pnlAbout = { title: 'About', id: 'pnlAbout', iconCls: 'icoAbout', defaults: {border: false}, items: [{ cls: 'sideItems', defaults: { border: false, cls: 'section' }, items: [{ contentEl: 'about_db' }, { contentEl: 'about_marker' }, { contentEl: 'about_post' }, { contentEl: 'about_comment' }, { contentEl: 'about_services' }, { cls: '', html: '
' }] }, { html: '

aquamap2

' }], listeners: { afterrender: function(){ $('#markerPic01').attr("src", am.getKindImage(1)); $('#markerPic02').attr("src", am.getKindImage(2)); $('#markerPic03').attr("src", am.getKindImage(3)); $('#markerPic04').attr("src", am.getKindImage(4)); $('#markerPic05').attr("src", am.getKindImage(5)); $('#markerPic06').attr("src", am.getKindImage(6)); $('#markerPic09').attr("src", am.getKindImage(9)); $('#gVerson').html(G_API_VERSION); }, show: function(){ Ext.Ajax.request({ url: am.URL.SCRIPT + '/count.php', method: 'GET', success: function(response, opts){ Ext.fly('about_db').show(); var cnt = Ext.decode(response.responseText); Ext.fly('cntReg').update(cnt['reg']); Ext.fly('cntComment').update(cnt['comment']); }, failure: function(){ Ext.fly('about_db').setStyle({ display: 'none' }); } }); } } }; am.vp.pnlTwitter = { title: 'Twitter', id: 'pnlTwitter', iconCls: 'icoTwitter', defaults: {border: false}, tbar: [{ text: 'アクアリム全般', handler: am.twitterSearch.createDelegate(this,[2]) },{ text: 'NA', handler: am.twitterSearch.createDelegate(this,[3]) },{ text: '#aquarium', handler: am.twitterSearch.createDelegate(this,[11]) },{ text: 'aquamap', handler: am.twitterSearch.createDelegate(this,[1]) /* },{ text: 'test4', handler: am.twitterSearch.createDelegate(this,[4]) */ }], items: [{ cls: 'sideItems', defaults: { border: false }, items: [{ html: '
' }, { xtype: 'dataview', id: 'dvTwitter', store: am.store.twitterSearch, tpl: am.template.twitterSearch, emptyText: '

Twitter検索 (テスト中)

No Results or API Error.

', emptyText: '

empty

', itemSelector: 'li' }, { cls: '', html: '
' }] }, { html: '

aquamap2

' }], listeners: { activate : function(){ if (am.twitter.channel == 0) am.twitter.channel = 2; am.twitterSearch(am.twitter.channel); } } }; /* id: 'pnlTwitterSearchAction', cls: '', items: [{ xtype: 'button', text: '検索', handler: function(){ am.twitterSearch(); } }, { xtype: 'checkbox', boxLabel: '絞り込み', }] */am.vp.pnlDump = new Ext.Panel({ title: 'object dump', id: 'pnlDump', layout: 'border', //border: true, defaults: {border: false}, items: [{ region: 'north', //border: true, html: '
', height: 200, autoScroll: true, split: true }, { region: 'center', //border: true, html: '
', autoScroll: true }] }); am.postPlace = function(isNewPlace){ var map; var marker; var fieldset = [{ xtype: 'fieldset', id: 'fsAttribute', border: false, autoHeight: true, labelAlign: 'top', defaultType: 'textfield', defaults: { width: 270 }, items: [{ xtype: 'hidden', id: 'fiaId', fieldLabel: 'ID', name: 'id' }, { xtype: 'hidden', id: 'fiaLat', fieldLabel: 'lat', name: 'lat' }, { xtype: 'hidden', id: 'fiaLng', fieldLabel: 'lng', name: 'lng' }, { id: 'fiaTitle', fieldLabel: '名称', name: 'title', allowBlank: false, blankText: '必須項目です!' },{ id: 'fiaKind', fieldLabel: '種類', name: 'kind', xtype: 'combo', mode: 'local', store: { xtype: 'arraystore', fields: [ {name: 'kindCode', type: 'int'}, {name: 'displayText', type: 'string'} ], data: [ //[1, 'アクアショップ'],am.getKindString [1, am.getKindString(1)], [2, 'ペットショップ'], [3, 'ホームセンター'], [4, '水族館'], [5, '展示水槽'], [6, 'イベント'], [7, '飲食店'], [9, 'その他'] ] }, width: 200, valueField: 'kindCode', displayField: 'displayText', forceSelection: true, triggerAction: 'all', editable: false, emptyText: '未分類' },{ id: 'fiaAddress', fieldLabel: '住所', name: 'address', xtype: 'textarea', grow: true, growMax: 100 },{ id: 'fiaTel', fieldLabel: '電話番号', name: 'tel' },{ id: 'fiaFax', fieldLabel: 'FAX番号', name: 'fax' },{ id: 'fiaUrl', fieldLabel: 'WEB', name: 'url', vtype: 'url' },{ /* id: 'cbgWith', xtype: 'checkboxgroup', fieldLabel: '取り扱い', columns: 1, items: [ {boxLabel: 'ADA(特約店)', id: 'fiaWithADA', name: 'withADA'}, {boxLabel: 'Do!aqua', id: 'fiaWithDoaqua', name: 'withDoaqua'}, {boxLabel: '淡水魚・古代魚・大型魚 (熱帯魚全般)', id: 'fiaWithFish', name: 'withFish'}, {boxLabel: '海水魚・サンゴ', id: 'fiaWithSwFish', name: 'withSwFish'}, {boxLabel: '金魚・めだか・錦鯉・日本産淡水魚', id: 'fiaWithGoldfish', name: 'withGoldfish'}, {boxLabel: 'CRS(レッドビーシュリンプ)', id: 'fiaWithShrimp', name: 'withShrimp'}, {boxLabel: '水草', id: 'fiaWithWeeds', name: 'withWeeds'} ] */ xtype: 'fieldset', id: 'fiaWith', //autoHeight: true, defaultType: 'checkbox', defaults: { fieldLabel: '', labelSeparator: '' }, items: [ {boxLabel: 'ADA (特約店)', id: 'fiaWithADA', name: 'withADA', fieldLabel: '取り扱い:', itemCls: 'topItem'}, {boxLabel: 'Do!aqua', id: 'fiaWithDoaqua', name: 'withDoaqua'}, {boxLabel: '淡水魚・古代魚・大型魚 (熱帯魚全般)', id: 'fiaWithFish', name: 'withFish'}, {boxLabel: '海水魚・サンゴ', id: 'fiaWithSwFish', name: 'withSwFish'}, {boxLabel: '金魚・めだか・錦鯉・日本産淡水魚', id: 'fiaWithGoldfish', name: 'withGoldfish'}, {boxLabel: 'CRS(レッドビーシュリンプ)', id: 'fiaWithShrimp', name: 'withShrimp'}, {boxLabel: '水草', id: 'fiaWithWeeds', name: 'withWeeds'} ] },{ id: 'fiaHours', fieldLabel: '営業時間', name: 'hours', xtype: 'textarea', grow: true, growMax: 100 },{ id: 'fiaHoliday', fieldLabel: '定休日', name: 'holiday', xtype: 'textarea', grow: true, growMax: 100 },{ id: 'fiaParking', fieldLabel: '駐車場', name: 'parking', xtype: 'textarea', grow: true, growMax: 100 },{ id: 'fiaFee', fieldLabel: '料金', name: 'fee', xtype: 'textarea', grow: true, growMax: 100 },{ id: 'fiaDescription', fieldLabel: 'その他(意見・感想等はクチコミでご記入くださいネ)', name: 'description', xtype: 'textarea', grow: true, growMax: 100 }] }]; var formPanel = new Ext.FormPanel({ items: fieldset, reader: am.reader.attribute, border: false }); var buttons = [{ text: '登録', iconCls: 'icoPost', handler: function(){ if (formPanel.getForm().isValid()) { am.dialog.place.disable(); var params = formPanel.getForm().getValues(); params['kind'] = Ext.getCmp('fiaKind').getValue(); Ext.Ajax.request({ url: am.URL.SCRIPT + '/postPlace.php', method: 'POST', params: params, success: function(response, opts){ am.dialog.place.hide(); if (response.responseText > 0) { var id = response.responseText; if (!am.dialog.isNewPlace) { am.loadAttribute(id, function(){ am.vp.pnlReg.scrollTo('#attribute', function(){ Ext.select('#attribute dl').highlight(); Ext.select('#attribute dd').highlight(); }); }) } else { if (am.place.serched) am.map.removeOverlay(am.place.serched.marker); am.serch.geo.combo.setValue(''); Ext.getCmp('btnClearSerched').disable(); }; am.updateRegs(id, true); } else { Ext.MessageBox.alert('エラー', '投稿に失敗しました (code: ' + response.responseText + ' )'); }; }, failure: function(response, opts){ Ext.Msg.alert('エラー', '通信に失敗しました。
' + response.responseText, function(){ am.dialog.place.hide(); }); } }); } else { Ext.MessageBox.alert('エラー', 'フォームの入力内容を確認してください!'); }; } }, { text: 'やり直す', iconCls: 'icoRefresh', handler: function(){ load(); } }, { text: 'キャンセル', iconCls: 'icoCancel', handler: function(){ am.dialog.place.hide(); } }]; function changeMaptype(){ if (map.getCurrentMapType() != this.mt) map.setMapType(this.mt); else this.toggle(true); }; am.dialog.place = new Ext.Window({ id: 'dlPostPlace', // for CSS title: '登録情報の編集', iconCls: 'icoEditAttr', modal: true, closable: true, closeAction: 'hide', width: 720, height: 460, minWidth: 720, minHeight: 460, maximizable: true, constrainHeader: true, border: false, layout: 'border', items: [{ region: 'center', id: 'pnlDpMap', defaults: {border: false}, layout: 'border', tbar: [{ text: '地図', id: 'btn_G_NORMAL_MAP', enableToggle: true, toggleGroup: 'mapType', pressed: true, mt: G_NORMAL_MAP, handler: changeMaptype }, { text: '航空写真', enableToggle: true, toggleGroup: 'mapType', mt: G_SATELLITE_MAP, handler: changeMaptype }, { text: '地図+写真', enableToggle: true, toggleGroup: 'mapType', mt: G_HYBRID_MAP, handler: changeMaptype }, { text: '地形', enableToggle: true, toggleGroup: 'mapType', mt: G_PHYSICAL_MAP, handler: changeMaptype }], items: [{ region: 'center', html: '
', listeners: { afterrender: function(){ createMap(); }, bodyresize: function(p, width, height){ if (map) map.checkResize(); } } }, { region: 'south', id: 'pnlAddressOnMarker', autoHeight: true, //autoScroll: true, bodyCssClass: 'wideLink', defaults: {border: false}, items: [{ html: 'マーカーの住所 by google (ドラッグして移動できます)

address

入力する' }] }] }, { region: 'east', id: 'pnlAttribute', bodyCssClass: 'attributeBody', width: 320, autoScroll: true, margins: '0 0 0 3', frame: true, items: formPanel }], buttons: buttons, buttonAlign: 'center', listeners: { show: function(){ this.center(); this.disable(); }, hide: function(){ var form = formPanel.getForm(); form.clearInvalid(); form.reset(); Ext.fly('dpMapCanvas').hide(); $('#pnlAttribute .attributeBody').scrollTo('#fsAttribute', 500, { offset: -30 }); Ext.getCmp('btn_G_NORMAL_MAP').toggle(true); map.setMapType(G_NORMAL_MAP); } } }); am.postPlace = function(isNewPlace){ this.dialog.isNewPlace = isNewPlace; this.dialog.place.show(); load(); }; return this.postPlace(isNewPlace); function createMap(){ var latlng = new GLatLng(am_initial_lat, am_initial_lng); map = new GMap2(Ext.getDom('dpMapCanvas')); map.setCenter(latlng, am.ZOOM.MAX); map.addControl(new GLargeMapControl3D()); map.enableScrollWheelZoom(); map.enableContinuousZoom(); marker = new GMarker(latlng, { icon: am.getKindIcon(9), draggable: true }); map.addOverlay(marker); GEvent.addListener(marker, 'dragend', function(){ var latlng = marker.getLatLng(); $('#fiaLat').val(latlng.lat()); $('#fiaLng').val(latlng.lng()); dispAddressOnMarker(); setTimeout(function(){ map.panTo(latlng); },500); }); }; function load(){ if (am.dialog.isNewPlace) { var serched = am.place.serched.data; $('#fiaId').val(0); $('#fiaLat').val(serched.lat); $('#fiaLng').val(serched.lng); //$('#fiaTitle').val(''); //$('#fiaKind').val(-2); Ext.getCmp('fiaKind').setValue(9); $('#fiaAddress').val(serched.title); //$('#fiaPref').val(''); //$('#fiaZip').val(''); //$('#fiaTel').val(''); //$('#fiaFax').val(''); //$('#fiaHours').val(''); //$('#fiaHoliday').val(''); //$('#fiaParking').val(''); //$('#fiaFee').val(''); //$('#fiaUrl').val(''); //$('#fiaDescription').val(''); onLoadSuccess(); } else { formPanel.getForm().load({ url: am.URL.SCRIPT + '/place.php', method: 'get', params: { c: 2, id: am.current.reg.data.id }, success: function(form, action) { onLoadSuccess(); }, failure: function(form, action) { Ext.Msg.alert('エラー', '読み込みエラーが発生しました。
編集を中止します。', function(){ am.dialog.place.hide(); }); } }); }; }; function onLoadSuccess(){ var latlng = new GLatLng($('#fiaLat').val(), $('#fiaLng').val()); map.setCenter(latlng, am.ZOOM.MAX); if (am.dialog.isNewPlace) marker.setImage(am.getKindImage(-2)); else marker.setImage(am.getKindImage(Ext.getCmp('fiaKind').getValue())); marker.setLatLng(latlng); dispAddressOnMarker(); am.dialog.place.enable(); Ext.fly('dpMapCanvas').fadeIn({ easing: 'easeOut', duration: am.fx.duration*2 }); }; function dispAddressOnMarker(){ am.geocoder.getLocations(marker.getLatLng(), function(locations){ if (locations.Status.code == G_GEO_SUCCESS) { $('#addressOnMarker').html(am.getAddrString(locations.Placemark[0].address)); }; }); }; }; am.dialog.insertAddress = function(){ $('#pnlAttribute .attributeBody').scrollTo('#fiaAddress', 500, { easing: 'swing', offset: -100, onAfter: function(){ $('#fiaAddress').val($('#addressOnMarker').html()); Ext.fly('fiaAddress').highlight('ff0000', { attr: 'color' }); } }); }; am.postComment = function(){ var fieldset = [{ xtype: 'fieldset', id: 'fsComment', border: false, autoHeight: true, labelAlign: 'top', defaultType: 'textfield', defaults: { width: 316 }, items: [{ xtype: 'hidden', id: 'ficId', fieldLabel: 'id', name: 'id', value: 0 }, { xtype: 'hidden', id: 'ficPlaceID', fieldLabel: 'placeID', name: 'placeID' }, { id: 'ficName', fieldLabel: '名前 (任意)', name: 'name' }, { id: 'ficUrl', fieldLabel: 'アドレス(ホームページやブログ等、任意)', name: 'url', vtype: 'url' }, { id: 'ficCommentText', fieldLabel: 'クチコミ (必須)', name: 'commentText', xtype: 'textarea', height: 200, allowBlank: false, blankText: '必須項目です!' }] }]; var formPanel = new Ext.FormPanel({ frame: true, items: fieldset }); var buttons = [{ text: '投稿する', iconCls: 'icoPost', handler: function(){ if (formPanel.getForm().isValid()) { am.dialog.comment.disable(); Ext.Ajax.request({ url: am.URL.SCRIPT + '/postComment.php', method: 'POST', params: formPanel.getForm().getValues(), success: function(response, opts){ am.dialog.comment.hide(); if (response.responseText > 0) { var id = am.current.reg.data.id; am.loadComment(id, function(){ var el = 'comment-' + response.responseText; am.vp.pnlReg.scrollTo('#'+el, function(){ Ext.fly(el).highlight(); }); }); am.updateRegs(id); } else { Ext.MessageBox.alert('エラー', '投稿に失敗しました (code: ' + response.responseText + ' )'); }; }, failure: function(response, opts){ Ext.Msg.alert('エラー', '通信に失敗しました。
' + response.responseText, function(){ am.dialog.comment.hide(); }); } }); } else { Ext.MessageBox.alert('エラー', 'フォームの入力内容を確認してください!'); }; } }, { text: 'キャンセル', iconCls: 'icoCancel', handler: function(){ am.dialog.comment.hide(); } }]; this.dialog.comment = new Ext.Window({ id: 'dlPostComment', title: 'クチコミの投稿', iconCls: 'icoAddComment', modal: true, closable: true, closeAction: 'hide', width: 360, resizable: false, constrainHeader: true, border: false, items: [{ id: 'commentTo', html: 'to:

タイトル

' }, formPanel], buttons: buttons, buttonAlign: 'center', listeners: { show: function(){ this.center(); this.disable(); }, hide: function(){ var form = formPanel.getForm(); form.clearInvalid(); form.reset(); } } }); this.postComment = function(){ this.dialog.comment.show(); $('#commentTo p').html(this.current.reg.data.title); $('#ficPlaceID').val(this.current.reg.data.id); this.dialog.comment.enable(); }; return this.postComment(); }; am.showLink = function(){ var fieldset = [{ xtype: 'fieldset', id: 'fsLink', border: false, autoHeight: true, labelAlign: 'top', defaults: { width: 330 }, items: [{ id: 'filUrl', xtype: 'textfield', fieldLabel: '現在のビューのURLアドレス', selectOnFocus: true, readOnly: true }, { html: '

※上記のURLアドレスから、直接、現在のマップビューにアクセスできます。

' }] }]; var formPanel = new Ext.FormPanel({ frame: true, items: fieldset }); var buttons = [{ text: 'OK', iconCls: 'icoOK', handler: function(){ am.dialog.link.hide(); } }]; this.dialog.link = new Ext.Window({ id: 'dlShowLink', title: 'リンクアドレス', iconCls: 'icoLink', modal: true, closable: true, closeAction: 'hide', width: 380, resizable: false, constrainHeader: true, border: false, items: formPanel, buttons: buttons, buttonAlign: 'center', listeners: { show: function(){ this.center(); var center = am.map.getCenter(); var addr = am.URL.WEB; var sep = '?'; if (addr.indexOf('?') > 0) sep = '&'; addr += sep + 'lat=' + center.lat(); addr += '&lng=' + center.lng(); addr += '&z=' + am.current.zoom; $('#filUrl').val(addr); }, hide: function(){ formPanel.getForm().reset(); } } }); this.showLink = function(){ this.dialog.link.show(); }; return this.showLink(); }; Ext.onReady(function(){ if (GBrowserIsCompatible()) { Ext.QuickTips.init(); Ext.form.Field.prototype.msgTarget = 'under'; am.vp.viewport = new Ext.Viewport({ layout: 'border', border: false, defaults: {border: false}, items: [{ region: 'north', height: 50, margins: '0 0 3 0', contentEl: 'header' }, { region: 'center', layout: 'border', margins: '0 0 3 3', defaults: {border: false}, bbar: am.vp.statusbar, items: [{ region: 'center', id: 'canvas', tbar: am.vp.toolbar, html: '
', border: true, listeners: { bodyresize: function(p, width, height){ if (am.map) { am.map.checkResize(); GEvent.trigger(am.map, 'moveend'); }; } } }, { region: 'south', id: 'nav', height: 160, layout: 'fit', split: true, collapsible: true, collapseMode: 'mini', header: false, items: am.vp.grdRegs, listeners: { beforecollapse: function(p, animate){ am.store.extractRegs = false; am.vp.grdRegs.hide(); }, collapse: function(){ Ext.getCmp('btnToggleNav').toggle(false); }, beforeexpand: function(p, animate){ am.vp.grdRegs.show(); }, expand: function(){ am.store.extractRegs = true; Ext.getCmp('btnToggleNav').toggle(true); } } }] }, { region: 'east', id: 'sidebar', layout: 'fit', width: 380, margins: '0 3 3 5', //collapsible: true, //collapseMode: 'mini', header: false, items: [{ xtype: 'tabpanel', id: 'tpSidebar', defaults: { border: false, autoScroll: true, bodyCssClass : 'sideBody' }, activeTab: 0, //items: [am2.vp.pnlHome, am2.vp.pnlReg, am2.vp.pnlTwitter, am2.vp.pnlAbout, am2.vp.pnlDump] items: [am.vp.pnlHome, am.vp.pnlReg, am.vp.pnlTwitter, am.vp.pnlAbout] }] }] }); am.vp.pnlReg.activate = function(){ Ext.getCmp('pnlReg').enable(); am.vp.pnlReg.activate = function(){ Ext.getCmp('tpSidebar').activate('pnlReg'); }; return am.vp.pnlReg.activate(); }; /* am.vp.pnlTwitter.activate = function(){ Ext.getCmp('pnlTwitter').enable(); am.vp.pnlTwitter.activate = function(){ Ext.getCmp('tpSidebar').activate('pnlTwitter'); }; return am.vp.pnlTwitter.activate(); }; */ am.vp.pnlReg.scrollTo = function(el, callback){ $('#pnlReg .sideBody').scrollTo(el, 100, { easing: 'swing', margin: -12, onAfter: function(){ if (callback) callback(); } }); }; am.serch = {}; am.serch.geo = { combo: new Ext.form.ComboBox({ typeAhead: false, width: 200, hideTrigger: true, emptyText: '住所を入力して検索', store: am.store.serched, tpl: am.template.serched, loadingText: '検索中...', itemSelector: 'div.searchedAddress', applyTo: 'search', queryParam: 'q', minChars: 2, onSelect: function(record){ var data ={}; data.id = 0; data.kind = -2; data.title = am.getAddrString(record.data.address); data.lat = record.data.point.coordinates[1]; data.lng = record.data.point.coordinates[0]; data.latlng = new GLatLng(data.lat, data.lng); if (am.place.serched) am.map.removeOverlay(am.place.serched.marker); am.place.serched = new am.Place(data); am.map.setCenter(data.latlng, Math.max(am.current.zoom, am.ZOOM.INDIVIDUAL)); am.map.addOverlay(am.place.serched.marker); am.place.serched.click(); this.collapse(); Ext.getCmp('btnClearSerched').enable(); }, onKeyUp : function(e){ if(this.editable !== false && !e.isSpecialKey()){ this.lastKey = e.getKey(); } } }), timeout: null, comboValue: '' }; am.serch.geo.focusCombo = function() { var serch = am.serch.geo; if (serch.comboValue != serch.combo.el.dom.value) { if (serch.combo.isExpanded()) serch.combo.collapse(); serch.combo.onTriggerClick(); serch.comboValue = serch.combo.el.dom.value; }; serch.timeout = setTimeout(am.serch.geo.focusCombo, 500); }; am.serch.geo.blurCombo = function() { clearTimeout(am.serch.geo.timeout); }; am.serch.geo.combo.on({ 'focus': am.serch.geo.focusCombo, 'blur': am.serch.geo.blurCombo }); am.createMap(); am.vp.grdRegs.hide(); am.loadRegs(function(){ am.filterRegs(function(){ am.vp.grdRegs.show(); am.createCluster(); // ローディングマスク解除 setTimeout(function(){ Ext.get('loading').remove(); Ext.get('loadingMask').fadeOut({ remove: true, duration: 0.5 }); }, 1000); }); }); $(window).unload(function(){ delete am.place; delete am.markers; am = null; GUnload(); // if (Ext.isGecko3) Components.utils.forceGC(); }); }; });