var charset="";
/**********************************************************************
*
* $Id: startUp.js,v 1.8 2006/12/14 17:24:41 lbecchi Exp $
*
* purpose: start up code to bootstrap initialization of kaMap within
* the sample interface. Examples of using many parts of
* the kaMap core api.
*
* purpose: This is the sample ka-Map interface. Feel free to use it
* as the basis for your own applications or just to find out
* how ka-Map works.
*
* author: Lorenzo Becchi and Andrea Cappugi (www.ominiverdi.org)
*
* ka-Explorer interface has been developer for Food and Agriculture
* Organization of the United Nations (FAO-UN)
*
*
**********************************************************************
*
* Copyright (c) 2006 Food and Agriculture Organization of the United Nations (FAO-UN)
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
**********************************************************************/
/******************************************************************************
*
* To customize startUp:
*
* 1) modify toolbar Layout
* act on screen.css file and modify the funcion myMapInitialized().
* If you change pan and identifyer images edit switchMode() function too.
*
*****************************************************************************/
var ICTMAP = null;
var ICTMAP_URL = "http:/"+"/map.kumamoto-net.ne.jp/ictmap/";
var ICTMAP_INIT = "/*init*/aszScales=new Array('600000','300000','100000','50000','25000','12500','10000','7500','5000','2500');defaultKihonLayer=new Array();defaultGeomLayer=new Array('4');var map = new _map({name:'gmap',title:'amakusaict',currentScale: 0,units:5,resolution:72,version:'',scales:aszScales});map.setDefaultExtents(129.942751522,32.0900215666,131.339655464,33.2329429742);map.setBackgroundColor('#9BAFCD');map.addLayer(new _layer( { name:'back',name2:'背景',visible:true,opacity:100,imageformat:'AGG_PNG24',queryable:false,tileSource:'auto',redrawInterval:-1,refreshInterval:-1,scales: new Array('1','1','1','1','1','1','1','1','1','1'),visibilityContorol:0}));map.addLayer(new _layer( { name:'base',name2:'地図標準アイコン',visible:false,opacity:100,imageformat:'AGG_PNG24',queryable:false,tileSource:'auto',redrawInterval:-1,refreshInterval:-1,scales: new Array('0','0','0','0','1','1','1','1','1','1'),visibilityContorol:1}));map.addLayer(new _layer( { name:'schoolarea',name2:'学校区域線',visible:false,opacity:100,imageformat:'AGG_PNG24',queryable:false,tileSource:'auto',redrawInterval:-1,refreshInterval:-1,scales: new Array('1','1','1','1','1','1','1','1','1','1'),visibilityContorol:1}));map.resolution = 72;this.addMap( map );this.tileWidth=256;this.tileHeight=256;this.server = '"+ICTMAP_URL+"';this.tileURL = 'tile.phtml';this.selectMap('gmap');this.hl='0';"
var ICTMAP_INIT_POINT = "130.71514754505813,32.8029555744417,12500";
//var oJsr = null;
/*
var myKaMap = myKaNavigator = myKaQuery = myScalebar = null;
var queryParams = null;
var mgpath = "";
*/
/**
* parse the query string sent to this window into a global array of key = value pairs
* this function should only be called once
*/
/*
function parseQueryString() {
queryParams = {};
var s=window.location.search;
if (s!='') {
s=s.substring( 1 );
var p=s.split('&');
for (var i=0;i
width){
this.scalebar.minWidth=width-10;
}
this.scalebar.maxWidth=width;
this.scalebar.update();
};
//コントローラーの表示・非表示
this.DspContorol = function(mode){
var obj = getRawObject(this.controlID);
if(mode){
this.dspContorol = true;
obj.style.display = 'block';
}else{
this.dspContorol = false;
obj.style.display = 'none';
}
};
//学校名の表示・非表示
this.DspSchoolname = function(mode){
var obj = getRawObject(this.schoolnameID);
if(mode){
this.dspContorol = true;
obj.style.display = 'block';
}else{
this.dspContorol = false;
obj.style.display = 'none';
}
};
//サブマップの表示・非表示
this.DspSubmap = function(mode){
var obj = getRawObject(this.submapID);
if(mode){
this.dspSubmap = true;
obj.style.display = 'block';
}else{
this.dspSubmap = false;
obj.style.display = 'none';
}
};
//this.ICTMAP = this.myKaNavigator = this.myKaQuery = this.myScalebar = null;
this.queryParams = null;
this.mgpath = "";
//SetCenter(x,y[,scale])
//指定した経度・経度を中心にして、指定された
//スケールで地図を表示する
//引数:経度、緯度、スケール
this.SetCenter = function(x,y){
var str = arguments[2];
if(str != null && str != ""){
var scale = convertNum(str);
if(this.CheckScale(scale)){
ICTMAP.zoomTo(x,y,scale);
}
}else{
ICTMAP.zoomTo(x,y);
}
};
//指定されたスケールに拡大・縮小する
//引数:スケール
this.SetZoom = function(scale){
if(this.CheckScale(scale)){
ICTMAP.zoomToScale(scale);
}
};
//妥当なスケールかどうかチェックする
this.CheckScale = function(scale){
var arrScales = ICTMAP.aMaps[ICTMAP.currentMap].getScales();
var arrLen = arrScales.length;
var matchFlg = false;
for(i=0;i 0){
this.arrOnclick[this.arrOnclickAnimeIdx]();
this.arrOnclickAnimeIdx++;
if(this.arrOnclickAnimeIdx == this.arrOnclick.length){
this.arrOnclickAnimeIdx=0;
}
}
}
//初期処理
if(initX != null && initY != null && initScale != null){
this.init(objname,initX,initY,initScale);
}else{
this.init(objname);
}
}
//*****************************
// ポイントを一つ追加する
// sakai
//*****************************
IctMap.prototype.AddPoint = function(pointid,lon,lat,icon,opts,pointName){
var my_point = ICTMAP.myXmlOverlay.addNewPoint(ICTMAP.USERPOINT_PREFIX+pointid, lon, lat,opts,pointName);
if(icon != null && typeof(icon) == "object"){
my_point.addGraphic(icon.Icon);
}else{
var my_symbol = new kaXmlSymbol();
my_symbol.size = 12;
my_symbol.color = '#ff0000';
my_point.addGraphic(my_symbol);
}
return my_point;
};
//*****************************
// ポイントを削除する(ユーザポイント)
// pointidがnullの場合ユーザポイントを全て削除する
// sakai
//*****************************
IctMap.prototype.RemovePoint = function(pointid){
if(pointid != null && pointid != ""){
ICTMAP.myXmlOverlay.removePoint(ICTMAP.USERPOINT_PREFIX+pointid);
}else{
ICTMAP.myXmlOverlay.removePoint("",ICTMAP.USERPOINT_PREFIX);
}
};
//*****************************
// アイコンオブジェクト
// sakai
//*****************************
function ictMapIcon(){
this.img_src = null;
this.icon_w = 0;
this.icon_h = 0;
/*this.markerOption = new GMarkerOptions();
this.markerOption.icon = new GIcon();
this.markerOption.icon.image = this.img_src;
this.markerOption.icon.size = null;*/
this.Icon = new kaXmlIcon();
this.Icon.img_src = this.img_src;
};
//*****************************
// 数値に変換する
// sakai
//*****************************
function convertNum(str){
try{
var dst = parseInt(str,10);
return dst;
}catch(e){
return null;
}
};
//*****************************
// イベントを追加する
// sakai
//*****************************
function addEvent(target, type, func){
if(target.attachEvent){
target.attachEvent("on" + type, func);
}else if(target.addEventListener){
target.addEventListener(type, func, true);
}else {
target["on" + type] = func;
}
};
/*
addEvent(window,"load",function(){
var css = document.createElement("link");
css.setAttribute("rel","stylesheet");
css.setAttribute("type","text/css");
css.setAttribute("href",ICTMAP.server+"ictmap.css");
var head = document.getElementsByTagName("head");
head[0].appendChild(css);
});
*/
//*****************************
// 初期処理
// sakai
//*****************************
IctMap.prototype.init = function(objname) {
initDHTMLAPI();
//window.onresize=drawPage;
//ベースHTMLを描画する
var targetObj = getRawObject(objname);
if(targetObj){
targetObj.innerHTML = getBaseHtml();
}else{
alert("マップ表示用HTMLオブジェクトが不正です");
return;
}
//VIEWPORTのサイズを設定
var mapWidth = getObjectWidth(targetObj);
var mapHeight = getObjectHeight(targetObj);
var viewport = getRawObject(this.CONST_VIEWPORT_ID);
viewport.style.width = mapWidth+"px";
viewport.style.height = mapHeight+"px";
ICTMAP = new kaMap(this.CONST_VIEWPORT_ID,"",ICTMAP_INIT);
ICTMAP.IctMap = this;
//var szMap = getQueryParam('map');
//var szExtents = getQueryParam('extents');
//var szCPS = getQueryParam('cps');
var szMap = "";
var szExtents = "";
var szCPS = "";
if(arguments.length > 2){
szCPS = arguments[1]+","+arguments[2]+","+arguments[3];
}
// デモ用にデフォルトを熊本市中心で表示
if(szCPS == ""){
szCPS = ICTMAP_INIT_POINT;
}
var gbLegendOpacityControl = false;
var gbLegendOrderControl = false;
var gbLegendQueryControl = false;
var legendOptions = {};
legendOptions.visibility = typeof gbLegendVisibilityControl != 'undefined' ? gbLegendVisibilityControl : true;
legendOptions.opacity = typeof gbLegendOpacityControl != 'undefined' ? gbLegendOpacityControl : true;
legendOptions.order = typeof gbLegendOrderControl != 'undefined' ? gbLegendOrderControl : true;
legendOptions.query = typeof gbLegendQueryControl != 'undefined' ? gbLegendQueryControl : true;
//var myKaLegend = new kaLegend( ICTMAP, 'legend', false, legendOptions);
var myKaKeymap = new kaKeymap( ICTMAP, this.CONST_SUBMAP_ID);
ICTMAP.kaKeymap = myKaKeymap;
myKaNavigator = new kaNavigator( ICTMAP );
myKaNavigator.activate();
myKaQuery = new kaQuery( ICTMAP, KAMAP_RECT_QUERY );
myKaRubberZoom = new kaRubberZoom( ICTMAP );
myKaTracker = new kaMouseTracker(ICTMAP);
myKaTracker.activate();
ICTMAP.registerForEvent( KAMAP_INITIALIZED, null, myInitialized );
ICTMAP.registerForEvent( KAMAP_MAP_INITIALIZED, null, myMapInitialized );
ICTMAP.registerForEvent( KAMAP_SCALE_CHANGED, null, myScaleChanged );
ICTMAP.registerForEvent( KAMAP_EXTENTS_CHANGED, null, myExtentChanged );
ICTMAP.registerForEvent( KAMAP_LAYERS_CHANGED, null, myLayersChanged );
ICTMAP.registerForEvent( KAMAP_LAYER_STATUS_CHANGED, null, myLayersChanged );
ICTMAP.registerForEvent( KAMAP_QUERY, null, myQuery );
ICTMAP.registerForEvent( KAMAP_MAP_CLICKED, null, myMapClicked );
ICTMAP.registerForEvent( KAMAP_MOUSE_TRACKER, null, myMouseMoved );
myScalebar = new ScaleBar(1);
myScalebar.divisions = 3;
myScalebar.subdivisions = 2;
myScalebar.minWidth = 100;
myScalebar.maxWidth = 200;
if(this.scalebarWidth != null){
myScalebar.maxWidth = this.scalebarWidth;
myScalebar.minWidth = this.scalebarWidth - 10;
getRawObject(this.scalebarID).style.width=this.scalebarWidth+"px";
}
myScalebar.place('scalebar');
this.scalebar = myScalebar;
//toolTip = new kaToolTip( ICTMAP );
ICTMAP.myXmlOverlay = new kaXmlOverlay( ICTMAP, 200);
//drawPage();
ICTMAP.initialize( szMap, szExtents, szCPS );
myKaSearch = new kaSearch( ICTMAP );
ICTMAP.myXmlOverlay.setBaseUrl();
//スタイルシート読み込み
if(ICTMAP.isIE6CSS&&!isFIREFOX){
var css = document.createElement("link");
css.setAttribute("rel","stylesheet");
css.setAttribute("type","text/css");
css.setAttribute("href",ICTMAP.server+"ictmap.css");
var head = document.getElementsByTagName("head")[0].appendChild(css);
}else{
var defaultStyle = document.createElement('style');
var styleText = '@import url(\"' + ICTMAP.server + 'ictmap.css\");';
var styleTextElem = document.createTextNode(styleText);
defaultStyle.appendChild(styleTextElem); //ここでエラーが出るときはDOCTYPEを調整
defaultStyle.type = 'text/css';
document.getElementsByTagName('head')[0].appendChild(defaultStyle);
}
/*
var tmp = "";
for(i in defaultStyle){
//console.log(i);
tmp += "," + i
}
window.clipboardData.setData("text",tmp);
*/
};
/**
* event handler for KAMAP_INITIALIZED.
*
* at this point, ka-Map! knows what map files are available and we have
* access to them.
*/
function myInitialized() {
//myMapInitialized( null, ICTMAP.getCurrentMap().name );
//dispOverLay();
//updateLinkToView();
}
/**
* event handler for KAMAP_MAP_INITIALIZED
*
* the scales are put into a select ... this will be used for zooming
*/
function myMapInitialized( eventID, mapName ) {
//get list of maps and populate the maps select box
var aMaps = ICTMAP.getMaps();
//update the scales select
var currentMap = ICTMAP.getCurrentMap();
var scales = currentMap.getScales();
var currentScale=ICTMAP.getCurrentScale();
//oSelect = document.toolbar.scales;
oSelect = getRawObject("toolbar_scales");
if(oSelect){
while( oSelect.options[0] ) oSelect.options[0] = null;
j=0;
//for(var i in scales)
for(i=0;i 50){
ICTMAP.myXmlOverlay.removePoint("",ICTMAP.BASEPOINT_PREFIX); // 標準ポイントを一旦削除
};
dispOverLayKihon(ICTMAP.dspLandmark);
var extents=ICTMAP.getGeoExtents();
dispSchoolName(extents);
}
function checkboxserialize2(elem,sep){
var dst = "";
if(elem){
len = elem.length;
if(len > 1){
for(i=0;iy: ' + roundIt(position.y,2);
*/
}
function myLayersChanged(eventID, map) {
updateLinkToView();
}
function updateLinkToView() {
var port = (window.location.port)? window.location.port : 80;
var url = window.location.protocol+'/'+'/'+window.location.host +':'+ port +''+window.location.pathname+'?';
var extents = ICTMAP.getGeoExtents();
var cx = (extents[2] + extents[0])/2;
var cy = (extents[3] + extents[1])/2;
var cpsURL = 'cps='+cx+','+cy+','+ICTMAP.getCurrentScale();
//var mapURL = 'map=' + ICTMAP.currentMap;
var theMap = ICTMAP.getCurrentMap();
var aLayers = theMap.getLayers();
var layersURL = 'layers=';
var sep = '';
for (var i=0;i' +
'miny: ' + roundIt(extents[1],2) +' ' +
'maxx: ' + roundIt(extents[2],2) +' ' +
'maxy: ' + roundIt(extents[3],2) +' ';
}
*/
}
function sendLinkToView(email,body) {
var mySubject = myUrlEncode('Authomatic ka-Map mail');
var myBody = myUrlEncode(body);
location.replace( 'mailto:' + email + '?subject=' + mySubject + '&body=' + body);
}
/**
* called when kaMap tells us the scale has changed
*/
function myScaleChanged( eventID, scale ) {
getRawObject("pointinfo").style.visibility='hidden'; // sakai
//var oSelect = document.toolbar.scales;
var oSelect = getRawObject("toolbar_scales");
if(oSelect){
for (var i=0; i= 1000000) {
scale = scale / 1000000;
scale = scale + " Million";
}
var outString = 'current scale 1:'+ scale;
getRawObject('scale').innerHTML = outString;
*/
}
/**
* called when the user changes scales. This will cause the map to zoom to
* the new scale and trigger a bunch of events, including:
* KAMAP_SCALE_CHANGED
* KAMAP_EXTENTS_CHANGED
*/
function mySetScale( scale ) {
ICTMAP.zoomToScale( scale );
}
/**
* called when the map selection changes due to the user selecting a new map.
* By calling ICTMAP.selectMap, this triggers the KAMAP_MAP_INITIALIZED event
* after the new map is initialized which, in turn, causes myMapInitialized
* to be called
*/
function mySetMap( name ) {
ICTMAP.selectMap( name );
}
function myQuery( eventID, queryType, coords ) {
var szLayers = '';
var layers = ICTMAP.getCurrentMap().getQueryableLayers();
if(layers.length==0) {
alert("No queryable layers at this scale and extent");
return;
}
for (var i=0;iProcessing query. please wait... ';
call('map_query_float.phtml?'+params,this, myQueryOutput);
// alert( "Map: " + cMap + " | Scale: " + scale + " | Extent: " + extent + " | QUERY: " + queryType + " " + coords + " on layers " + szLayers );
}
function myQueryOutput (szText){
getRawObject('queryOut').innerHTML=szText;
}
function myMapClicked( eventID, coords ) {
//alert( 'myMapClicked('+coords+')');
//ICTMAP.zoomTo(coords[0],coords[1]);
}
function myZoomIn() {
ICTMAP.zoomIn();
}
function myZoomOut() {
ICTMAP.zoomOut();
}
function myPrint(output_type) {
var szLayers = '';
var szOpacitys = '';
var layers = ICTMAP.getCurrentMap().getLayers();
for (var i=0;i
読み込み中
";
return baseHtml;
}
/************************************************************************************/
/*
IctMap 機能追加クラス
2010.02.19 M.KAKIMOTO
*/
/************************************************************************************/
/****************************************************************/
/*
(method)IctMap.AddPolyline
マップ上に多角線を引きます。
id : ポイントID (多角線の開始位置のポイント)
coordinates : "経度 緯度,経度 緯度" の形式の文字列
options : オプション
{
color : "線の色",
stroke : "ラインの太さ(pixel)",
opacity : "透明度(1.0で不透明、0.0で完全透明)"
}
(戻り値)
開始点のkaXmlPointクラス
*/
/****************************************************************/
IctMap.prototype.AddPolyline = function(id, coordinates, options)
{
return this.__AddMultiPointObject(id, coordinates, options, kaXmlLinestring);
};
/****************************************************************/
/*
(method)IctMap.AddPolygon
マップ上に多角形を作成します。
id : ポイントID (多角線の開始位置のポイント)
coordinates : "経度 緯度,経度 緯度" の形式の文字列
options : オプション
{
color : "線の色",
stroke : "ラインの太さ(pixel)",
opacity : "透明度(1.0で不透明、0.0で完全透明)"
}
(戻り値)
開始点のkaXmlPointクラス
*/
/****************************************************************/
IctMap.prototype.AddPolygon = function(id, coordinates, options)
{
return this.__AddMultiPointObject(id, coordinates, options, kaXmlPolygon);
};
/****************************************************************/
/*
(method)IctMap.__AddMultiPointObject
PolylineまたはPolygon生成の共通処理です。
id : ポイントID (多角線の開始位置のポイント)
coordinates : "経度 緯度,経度 緯度" の形式の文字列
options : オプション
{
color : "線の色",
stroke : "ラインの太さ(pixel)",
opacity : "透明度(1.0で不透明、0.0で完全透明)"
}
_class : 生成するクラス(kaXmlLinestringまたはkaXmlPolygonを想定)
(戻り値)
開始点のkaXmlPointクラス
*/
/****************************************************************/
IctMap.prototype.__AddMultiPointObject = function(id, coordinates, options, _class)
{
var op = {color:"", stroke:"", opacity:""};
if(options)
{
for(var o in op)
{
op[o] = (options[o]) ? options[o] : "";
}
}
op.color = (op.color.length == 0) ? "black" : op.color;
op.stroke = (op.stroke.length == 0) ? "1" : op.stroke;
op.opacity = (op.opacity.length == 0) ? "1" : op.opacity;
var coords = coordinates.split(",");
var pos = coords[0].split(/\s/);
var x = parseFloat(pos[0]);
var y = parseFloat(pos[1]);
var point = ICTMAP.myXmlOverlay.addNewPoint(ICTMAP.USERPOINT_PREFIX+id, x, y);
var polyline = new _class(point);
polyline.readCoordinates(point, coordinates);
for(var o in op)
{
polyline[o] = op[o];
}
point.addGraphic(polyline);
return point;
}
/****************************************************************/
/*
(method)IctMap.RemovePolyline
マップ上の多角線を削除します。
id : ポイントID (多角線の開始位置のポイント)
(戻り値)
void
*/
/****************************************************************/
IctMap.prototype.RemovePolyline = function(id)
{
var reg;
if(id != null && id != ""){
var pointid = ICTMAP.USERPOINT_PREFIX+id;
reg = new RegExp("^"+pointid+"$");
}else{
reg = new RegExp("^" + ICTMAP.USERPOINT_PREFIX);
}
for(var i=0; i 0)
{
var o = this.GetDrawObject();
var m = this.GetDrawMethod();
var p = m.apply
(
o,
[this.TOOL_LINE_PREFIX, coordinates.join(","), this.LineStyle]
);
var canvases = p.div.getElementsByTagName("canvas");
if(canvases.length > 0)
{
this.Canvas = canvases[0];
}
this.StartPoint = p;
var drawObj = p.graphics[0];
var scf = ICTMAP.myXmlOverlay.kaMap.getCurrentScale() / drawObj.maxScale;
this.PixelCollection = [];
for(var i=0; i"
+ "このポイントを削除する ";
//ポイント追加のメニューリンク
var insertLink =
""
+ "間にポイントを追加する ";
//ポイントの作成
var x = this.PointCollection[index].x;
var y = this.PointCollection[index].y;
var point =
ICTMAP.myXmlOverlay.addNewPoint(id+"p"+index, x, y);
//ポイントアイコンの作成(divタグ)
var div = this.CreatePointIconElement();
point.div.appendChild(div);
//アイコンの位置がポイントの中心に行くように位置を調整
var top = point.div.style.top.replace("px","");
var left = point.div.style.left.replace("px","");
var width = div.style.width.replace("px","");
var height = div.style.height.replace("px","");
top = parseInt(top)-parseInt(parseInt(height)/2);
left = parseInt(left)-parseInt(parseInt(width)/2);
point.div.style.top = top + "px";
point.div.style.left = left + "px";
//イベントハンドラの登録
var self = this;
//ツールが有効じゃない場合は、イベントを登録しない。
if(!this.IsActive)
{
div.style.cursor="";
return point;
}
//ポイントのクリック(ドラッグ開始)
div.onmousedown = function()
{
if(self.DraggingPointIndex > -1) return;
self.DraggingPointIndex = index;
self.OnDragPointStart.apply(self, arguments);
self._OnDragPointStart.apply(self, arguments);
};
//ポイント削除メニューのクリック(グローバルスコープに関数追加)
window["__ictmap_tools_activetool_removepoint"] = function()
{
self.IsClickLocked = true;
self.RemovePoint.apply(self, arguments);
clearOverlaysymbolhtml();
if(typeof self.OnAfterRemovePoint == "function")
{
self.OnAfterRemovePoint.apply(self, arguments);
}
}
//ポイント追加メニューのクリック
window["__ictmap_tools_activetool_insertpoint"] = function()
{
self.IsClickLocked = true;
self.InsertAfterPoint.apply(self, arguments);
clearOverlaysymbolhtml();
if(typeof self.OnAfterInsertPoint == "function")
{
self.OnAfterInsertPoint.apply(self,arguments);
}
}
var menuString = removeLink;
if(index < this.PointCollection.length-1)
{
menuString += insertLink;
}
//ポイントをクリックしたときのポップアップ表示
point.div.onclick = function()
{
self.OnClickPoint(self, arguments);
self.IsPopupMenuOpened = true;
clickIconEvent(point, menuString);
//clearOverlaysymbolhtmlを呼び出したときポイントが
//追加されないようにオーバーライド
var clearOverlaysymbolhtml_ = clearOverlaysymbolhtml;
clearOverlaysymbolhtml = function()
{
self.IsClickLocked = true;
self.IsPopupMenuOpened = false;
clearOverlaysymbolhtml_();
clearOverlaysymbolhtml = clearOverlaysymbolhtml_;
};
};
return point;
},
/************************************************************/
/*
(method) CreatePointIconElement
ドラッグ用のポイントアイコンを生成します。
*/
/************************************************************/
CreatePointIconElement : function()
{
var div = document.createElement("div");
for(var p in this.PointStyle)
{
div.style[p] = this.PointStyle[p];
}
return div;
},
/************************************************************/
/*
(public virtual method) GetDrawMethod
本クラスはTools.Polygonクラスに継承されます。
その為、描画メソッドをクラスによって選択できるようにしました。
このメソッドは、Tools.Polygonクラスでoverrideされます。
*/
/************************************************************/
GetDrawMethod : function()
{
return ICTMAP.IctMap.AddPolyline;
},
/************************************************************/
/*
(public virtual method) GetDrawObject
本クラスはTools.Polygonクラスに継承されます。
その為、描画オブジェクトをクラスによって選択できるようにしました。
このメソッドは、Tools.Polygonクラスでoverrideされます。
*/
/************************************************************/
GetDrawObject : function()
{
return ICTMAP.IctMap;
},
/************************************************************/
/*
(property) LockDblClickEvent
OnDblClickイベントを排他的にロック
*/
/************************************************************/
LockDblClickEvent : function()
{
var self = this;
this.ExclusiveEvents.LockEventHandler
(
"dblclick",
function(e)
{
var p = ICTMAP.IctMap.Tools.ToGeometory(e);
self.OnDblClick.apply(self, arguments);
self._OnDblClick.apply(self, arguments);
}
);
},
/************************************************************/
/*
(method) OnDblClick
ダブルクリックしたときに発生するイベントのイベントハンドラです。
*/
/************************************************************/
OnDblClick : function()
{
},
/************************************************************/
/*
(private method) _OnDblClick
ダブルクリックしたときに発生するイベントのイベントハンドラです。
(*)ユーザーに公開していない処理部分です。
*/
/************************************************************/
_OnDblClick : function(e)
{
if(this.IsClosed) return;
var geo = ICTMAP.IctMap.Tools.ToGeometory(e);
this.PointCollection.push(geo);
this._createBox(geo);
if(this.PointCollection.length > 0)
{
this.IsClosed = true;
this.IsClickLocked = true;
this.Reflesh();
}
},
/************************************************************/
/*
(method) OnMapClick
MAPをクリックしたときに発生するイベントハンドラです。
*/
/************************************************************/
OnMapClick : function()
{
},
/************************************************************/
/*
(private method) _OnMapClick
MAPをクリックしたときに発生するイベントハンドラです。
(*)ユーザーに公開していない処理部分です。
*/
/************************************************************/
_OnMapClick : function()
{
},
/************************************************************/
/*
(private method) _OnMapClickTrigger
イベントハンドラとして登録される処理実体です。
_OnMapClickを、thisをこのクラスとして実行します。
*/
/************************************************************/
_OnMapClickTrigger : function()
{
},
/************************************************************/
/*
(private method) _OnMouseEventsTrigger
マウスイベントのブラウザ依存を吸収します。
*/
/************************************************************/
_OnMouseEventsTrigger : function(eventid, p)
{
if(this.StartPoint == null)
{
return;
}
var gp = {x:(p.x) ? p.x : p[0], y:(p.y) ? p.y :p[1]};
gp = {x:parseFloat(gp.x), y:parseFloat(gp.y)};
if(gp.x > this.Box.maxX || gp.y > this.Box.maxY || gp.x < this.Box.minX || gp.y < this.Box.minY)
{
if(this.IsMouseOverPosition)
{
this.OnMouseOut.apply(this, arguments);
this.IsMouseOverPosition = false;
}
return;
}
var pp = ICTMAP.IctMap.Tools.ToCanvasOffset(this.StartPoint.graphics[0], gp);
if(this.IsMouseOver(pp))
{
if(!this.IsMouseOverPosition)
{
this.OnMouseOver.apply(this, arguments);
this.IsMouseOverPosition = true;
}
}
else
{
if(this.IsMouseOverPosition)
{
this.OnMouseOut.apply(this, arguments);
this.IsMouseOverPosition = false;
}
}
},
/************************************************************/
/*
(method) OnDragPointStart
ポイントのドラッグ開始のイベントハンドラです。
*/
/************************************************************/
OnDragPointStart : function()
{
},
/************************************************************/
/*
(method) OnDragPoint
ポイントのドラッグ中のイベントハンドラです。
(*)ユーザーに公開していない処理部分です。
*/
/************************************************************/
OnDragPoint : function()
{
},
/************************************************************/
/*
(method) OnDragPointEnd
ポイントのドラッグ終了のイベントハンドラです。
*/
/************************************************************/
OnDragPointEnd : function()
{
},
/************************************************************/
/*
(private method) _OnDragPointStart
ポイントのドラッグ開始のイベントハンドラです。
(*)ユーザーに公開していない処理部分です。
*/
/************************************************************/
_OnDragPointStart : function()
{
var self = this;
//地図フィールドのonmousedownと、onmouseupを無効化
this.ExclusiveEvents.LockEventHandler("mousedown", null);
this.ExclusiveEvents.LockEventHandler("mouseup", null);
//移動させる前の座標情報を保存
var startCoordinates = this.GetCoordinates();
//onmousemoveを排他的に上書き
this.ExclusiveEvents.LockEventHandler
(
"mousemove",
function()
{
self._OnDragPoint.apply(self, arguments);
self.OnDragPoint.apply(self, arguments);
}
);
//ドラッグ終了はどこからでもハンドリング出来るように
//document.bodyにセット
this.BodyOnMouseUp = document.body.onmouseup;
document.body.onmouseup = function()
{
//少しでも座標の変更があればドラッグとみなす
if(startCoordinates != self.GetCoordinates())
{
self.OnDragPointEnd.apply(self, arguments);
}
self._OnDragPointEnd.apply(self, arguments);
};
},
/************************************************************/
/*
(private method) _OnDragPoint
ポイントのドラッグ中のイベントハンドラです。
(*)ユーザーに公開していない処理部分です。
*/
/************************************************************/
_OnDragPoint : function(e)
{
//マウスの位置情報を緯度・経度に変換
var geo = ICTMAP.IctMap.Tools.ToGeometory(e);
//位置情報をドラッグ中のポイントに再セット
this.PointCollection[this.DraggingPointIndex] = geo;
this.Box = {maxX:0, maxY:0, minX:0,maxY:0};
for(var i=0; ieのベクトル
var se = {x:e.x-s.x, y:e.y-s.y};
//s-->eに垂直で交わり、sを通る座標
var sp = {x:se.y*-1 + s.x, y:se.x + s.y};
//s-->eに垂直で交わり、eを通る座標
var ep = {x:se.y*-1 + e.x, y:se.x + e.y};
// sp、epに対してpの位置を判定
var sd = this._getDistancePerpendicular(sp, s, p);
var ed = this._getDistancePerpendicular(ep, e, p);
return (sd <= 0 && ed >= 0);
},
/************************************************************/
/*
(private method) _getDistancePerpendicular
2点が結ぶラインに対して、任意の点が垂線を引ける位置にある時、
任意の位置からラインまでの距離を測ります。
(s-->eのラインに対して、pから垂線を引き、その交点とpとの距離を測ります。)
s : 始点の{x:x, y:y}
e : 終点の{x:x, y:y}
p : 任意の{x:x, y:y}
(戻り値)
ライン|se|に対するpからの距離。
正の値 ==> ライン|se|のベクトルに対して左
負の値 ==> ライン|se|のベクトルに対して右
*/
/************************************************************/
_getDistancePerpendicular : function(s, e, p)
{
//s-->p のベクトル
var sp = {x:p.x-s.x, y:p.y-s.y};
//s-->e のベクトル
var se = {x:e.x-s.x, y:e.y-s.y};
//seの長さ
var d = Math.sqrt(se.x * se.x + se.y * se.y);
if(d == 0)
{
//seの長さ0は点なので、sとpとの距離を求める
return Math.sqrt( sp.x * sp.x + sp.y * sp.y );
}
/* s-->pのベクトル|sp| * sin(@) ==> 距離d
* 外積の公式 sp * se = |sp| |se| sin(@) から
* d= |sp| sin(@) = (sp*se) / |se| と考える
*/
return (sp.x*se.y - sp.y*se.x) / d;
},
/************************************************************/
/*
(private method) _createBox
バウンディングボックスを作成します。
*/
/************************************************************/
_createBox : function(p)
{
this.Box.maxX = (this.Box.maxX < p.x) ? p.x : this.Box.maxX;
this.Box.maxY = (this.Box.maxY < p.y) ? p.y : this.Box.maxY;
this.Box.minX = (this.Box.minX ==0 || this.Box.minX > p.x) ? p.x : this.Box.minX;
this.Box.minY = (this.Box.minY ==0 || this.Box.minY > p.y) ? p.y : this.Box.minY;
}
};
/***********************************************************************************/
/*
(class)IctMap.Tools.Polygon extends IctMap.Tools.Polyline
IctMap上に、多角形を入力する為のUIツールです。
*/
/***********************************************************************************/
IctMap.prototype.Tools.Polygon = function()
{
this.Initialize.apply(this, arguments);
}
//extends IctMap.Tools.Polyline
for(var p in IctMap.prototype.Tools.Polyline.prototype)
{
IctMap.prototype.Tools.Polygon.prototype[p] = IctMap.prototype.Tools.Polyline.prototype[p];
}
IctMap.prototype.Tools.Polygon.prototype["parent"] = IctMap.prototype.Tools.Polyline.prototype;
var __ictmap_tools_polygon_prototype =
{
/************************************************************/
/*
(property) IsMouseOverPosition
マウスがポリゴン上に乗った事を示します。
*/
/************************************************************/
IsMouseOverPosition : false,
/************************************************************/
/*
(property) IsCanvasMouseOutOccured
canvasに対するマウスアウトイベントの発生を保持します。
(*)IE用
*/
/************************************************************/
IsCanvasMouseOutOccured : false,
/************************************************************/
/*
(property) Initialize
コンストラクタ
*/
/************************************************************/
Initialize : function()
{
this.parent.Initialize.apply(this, arguments);
this.TOOL_PREFIX = "_polygon_"
this.TOOL_LINE_PREFIX = "line_polygon";
this.LockDblClickEvent();
var onmapclick = this.OnMapClick;
var self = this;
this.OnMapClick = function()
{
if(!self.IsClosed)
{
onmapclick.apply(self, arguments);
}
};
ICTMAP.registerForEvent(KAMAP_MAP_CLICKED, this, this._OnMouseEventsTrigger);
},
/************************************************************/
/*
(method) OnClick
マウスがポリゴン上をクリックした時、発生するイベント
*/
/************************************************************/
OnClick : function()
{
},
/************************************************************/
/*
(override method) RemovePoint
ポイント配列からポイントを削除します。
*/
/************************************************************/
RemovePoint : function(index)
{
this.PointCollection.splice(index, 1);
if(this.PointCollection.length < 3)
{
this.IsClosed = false;
}
this.Reflesh();
},
/************************************************************/
/*
(override method) AfterReflesh
ポリゴンを描画後の処理です。
*/
/************************************************************/
AfterReflesh : function()
{
if(this.Canvas == null) return;
var self = this;
},
/************************************************************/
/*
(private orveride method) _OnMouseEventsTrigger
マウスイベントのブラウザ依存を吸収します。
*/
/************************************************************/
_OnMouseEventsTrigger : function(eventid, p)
{
if(!this.IsClosed) return;
var gp = {x:(p.x) ? p.x : p[0], y:(p.y) ? p.y :p[1]};
gp = {x:parseFloat(gp.x), y:parseFloat(gp.y)};
if(gp.x > this.Box.maxX || gp.y > this.Box.maxY || gp.x < this.Box.minX || gp.y < this.Box.minY)
{
if(this.IsMouseOverPosition)
{
this.OnMouseOut.apply(this, arguments);
this.IsMouseOverPosition = false;
}
return;
}
var pp = ICTMAP.IctMap.Tools.ToCanvasOffset(this.StartPoint.graphics[0], gp);
switch(eventid)
{
case KAMAP_MOUSE_TRACKER :
if(this.IsMouseOver(gp))
{
if(this.IsMouseOverPosition) return;
this.OnMouseOver.apply(this, arguments);
this.IsMouseOverPosition = true;
}
else
{
if(!this.IsMouseOverPosition) return;
if(!this.parent.IsMouseOver.apply(this, [pp]))
{
this.OnMouseOut.apply(this, arguments);
this.IsMouseOverPosition = false;
}
}
return;
case KAMAP_MAP_CLICKED :
if(this.IsMouseOver(gp))
{
this.OnClick.apply(this, arguments);
}
return;
default : return;
}
},
/************************************************************/
/*
(override method) GetDrawMethod
本クラスのデータを画面に描画するメソッドを取得します。
*/
/************************************************************/
GetDrawMethod : function()
{
return (this.IsClosed) ? ICTMAP.IctMap.AddPolygon : ICTMAP.IctMap.AddPolyline;
},
/************************************************************/
/*
(override method) GetDrawObject
本クラスのデータを画面に描画するオブジェクトを取得します。
*/
/************************************************************/
GetDrawObject : function()
{
return ICTMAP.IctMap;
},
/************************************************************/
/*
(override method) IsMouseOver
マウスが多角形の内点を指しているかを判定します。
*/
/************************************************************/
IsMouseOver : function(point)
{
var geo = point;
var coordinates = [];
for(var i=0; i 0)
{
var st = coordinates[0];
var ed = coordinates[coordinates.length-1];
if(st.x != ed.x || st.y != ed.y)
{
coordinates.push(coordinates[0]);
}
}
geo.x = parseFloat(geo.x);
geo.y = parseFloat(geo.y);
var clossLineCount = 0;
var geo0 = coordinates[0];
var isClossX0 = (geo.x <= geo0.x);
var isClossY0 = (geo.y <= geo0.y);
for(var i=1; i 2 &&
Math.abs(startp.y - pos.y) > 2)
{
self.OnPointDragEnd.apply(self, [point, -1, g]);
}
else
{
self.OnPointClick.apply(self, [point, KAMAP_MAP_CLICKED, g]);
}
document.body.onmouseup = bodymouseup;
return false;
}
self.PointExclusiveEvents.ReleseEventHandler("mousedown");
return false;
}
);
}
},
/************************************************************/
/*
(method) _OnPointClickEventTrigger
レイヤの重なりにより、点へのクリックイベント(ドラッグイベント)が
発生しない問題に対応します。
*/
/************************************************************/
_OnPointClickEventTrigger : function(eventid, p)
{
if(this.BaloonOpenObject != null) return;
p = {x:(p.x)?p.x:p[0], y:(p.y)?p.y:p[1]};
var pixes = ICTMAP.geoToPix(p.x, p.y);
var x = pixes[0];
var y = pixes[1];
var top = (y - ICTMAP.yOrigin);
var left = (x - ICTMAP.xOrigin);
var handlerSetten = false;
for(var i=this.PointCollection.length-1; i>-1; i--)
{
var point = this.PointCollection[i];
var obj = point.div;
var pointx = parseInt(point.div.style.left);
var pointy = parseInt(point.div.style.top);
var iconw = (point.graphics[0].icon_w) ? parseInt(point.graphics[0].icon_w) : 0;
var iconh = (point.graphics[0].icon_h) ? parseInt(point.graphics[0].icon_h) : 0;
var isover =
(
left >= pointx-(iconw/2) && left <= pointx+(iconw/2)
&& top >= pointy-(iconh/2) && top <= pointy+(iconh/2)
);
if(isover)
{
this._OnPointMouseOver.apply(this, [point, eventid, p]);
point["isover"] = true;
if(!handlerSetten)
{
this.SetPointEventHandler(point, p);
handlerSetten = true;
}
}
else
{
if(point["isover"])
{
this._OnPointMouseOut.apply(this, [point, eventid, p]);
point["isover"] = false;
}
}
}
if(!handlerSetten)
{
this.PointExclusiveEvents.ReleseEventHandler("mousedown");
this.PointExclusiveEvents.ReleseEventHandler("mousemove");
}
},
/************************************************************/
/*
(method) OnToolMouseOver
ツールからマウスカーソルが触れた時に発生するイベントです。
tool : イベントを発生させたツールのインスタンスです。
eventid : 発生したイベントID
p : ポイントの緯度・経度
*/
/************************************************************/
OnToolMouseOver : function()
{
},
/************************************************************/
/*
(method) OnToolMouseOut
ツールからマウスカーソルが離れた時に発生するイベントです。
tool : イベントを発生させたツールのインスタンスです。
eventid : 発生したイベントID
p : ポイントの緯度・経度
*/
/************************************************************/
OnToolMouseOut : function(tool)
{
},
/************************************************************/
/*
(method) OnToolClick
ツールをクリックした時に発生するイベントです。
tool : イベントを発生させたツールのインスタンスです。
eventid : 発生したイベントID
p : ポイントの緯度・経度
*/
/************************************************************/
OnToolClick : function()
{
},
/************************************************************/
/*
(method) OnToolDblClick
ツールをダブルクリックした時に発生するイベントです。
tool : イベントを発生させたツールのインスタンスです。
eventid : 発生したイベントID
p : ポイントの緯度・経度
*/
/************************************************************/
OnToolDblClick : function()
{
},
/************************************************************/
/*
(method) OnPointAdded
ポイントが追加されたときに発生します。
p : 追加されたkaXmlPointオブジェクト
*/
/************************************************************/
OnPointAdded : function(p)
{
},
/************************************************************/
/*
(method) OnPointClick
点をクリックした時に発生するイベントです。
p : クリックされたkaXmlPointオブジェクト
*/
/************************************************************/
OnPointClick : function(p)
{
},
/************************************************************/
/*
(method) OnPointDragStart
点や多角線・多角形の関節をドラッグしたとき発生するイベントです。
tool : kaXmlPointオブジェクト無いし、Polyline または Polygonオブジェクト
*/
/************************************************************/
OnPointDragStart : function(tool)
{
},
/************************************************************/
/*
(method) OnPointDrag
点や多角線・多角形の関節をドラッグ中に発生するイベントです。
tool : kaXmlPointオブジェクト無いし、Polyline または Polygonオブジェクト
*/
/************************************************************/
OnPointDrag : function(tool)
{
},
/************************************************************/
/*
(method) OnPointDragEnd
点や多角線・多角形の関節のドラッグが終了したときに、
発生するイベントです。
tool : kaXmlPointオブジェクト無いし、Polyline または Polygonオブジェクト
*/
/************************************************************/
OnPointDragEnd : function(tool)
{
},
/************************************************************/
/*
(method) OnPointMouseOver
ポイントにマウスが乗った時の処理です。
*/
/************************************************************/
OnPointMouseOver : function(p)
{
},
/************************************************************/
/*
(method) OnPointMouseOver
ポイントからマウスが離れた時の処理です。
*/
/************************************************************/
OnPointMouseOut : function(p)
{
},
/************************************************************/
/*
(method) OnCloseBaloon
バルーン(吹き出し)が閉じられた時発生するイベントです。
*/
/************************************************************/
OnCloseBaloon : function()
{
},
/************************************************************/
/*
(method) OnAfterInsertPoint
多角線・多角形にポイントを追加したときに発生するイベントです。
*/
/************************************************************/
OnAfterInsertPoint : function()
{
},
/************************************************************/
/*
(method) OnAfterRemovePoint
多角線・多角形からポイントを削除したときに発生するイベントです。
*/
/************************************************************/
OnAfterRemovePoint : function()
{
},
/************************************************************/
/*
(method) OnToolActive
ツールのActivateメソッドが呼び出された時実行されます。
*/
/************************************************************/
OnToolActive : function()
{
},
/************************************************************/
/*
(method) OnToolDeactive
ツールのDeactivateメソッドが呼び出された時実行されます。
*/
/************************************************************/
OnToolDeactive : function()
{
},
/************************************************************/
/*
(method) _OnPointMouseOver
ポイントにマウスが乗った時の処理です。
*/
/************************************************************/
_OnPointMouseOver : function(p, eventid, g)
{
if(this.BaloonOpenObject == null) this._AddNameList(p, g);
},
/************************************************************/
/*
(method) _OnPointMouseOver
ポイントからマウスが離れた時の処理です。
*/
/************************************************************/
_OnPointMouseOut : function(p, eventid, g)
{
this._RemoveNameList(p, g);
},
/************************************************************/
/*
(method) _OnToolMouseOver
ツールからマウスカーソルが離れた時に発生するイベントです。
本クラスは既定の動作として、ツールを有効(Activate)にします。
*/
/************************************************************/
_OnToolMouseOver : function(tool, eventid, p)
{
if(this.BaloonOpenObject ==null) this._AddNameList(tool, p);
if(!this.IsEditable) return;
if(this.ActiveTool!=null)
{
if
(
this.ActiveTool.DraggingPointIndex == -1
&& this.ActiveTool.IsClosed
&& !this.ActiveTool.IsMouseOverPosition
&& !this.ActiveTool.IsPopupMenuOpened
)
{
this.ChangeActiveTool(tool);
}
}
else
{
if(this.BaloonOpenObject == null)
{
this.ChangeActiveTool(tool);
}
}
},
/************************************************************/
/*
(method) _OnToolMouseOut
ツールからマウスカーソルが離れたときに発生するイベントです。
本クラスは既定の動作として、ツールを無効(Deactivate)にします。
*/
/************************************************************/
_OnToolMouseOut : function(tool)
{
this._RemoveNameList(tool);
if(!this.IsEditable) return;
if(this.ActiveTool!=null && tool.IsActive)
{
if
(
this.ActiveTool.DraggingPointIndex == -1
&& this.ActiveTool.IsClosed
&& !this.ActiveTool.IsPopupMenuOpened
)
{
tool.Deactivate(true);
}
}
},
/************************************************************/
/*
(method) _OnToolClick
ツールをクリックした時に発生するイベントです。
本クラスは既定の動作としてツールを有効(Activate)にします。
*/
/************************************************************/
_OnToolClick : function(tool)
{
if(!this.IsEditable) return;
if
(
this.ActiveTool != null
&& !tool.IsActive
&& this.ActiveTool.IsClosed
&& this.BaloonOpenObject == null
)
{
this.ChangeActiveTool(tool);
}
else
{
if(this.ActiveTool == null)
{
this.ChangeActiveTool(tool);
}
}
},
/************************************************************/
/*
(method) _OnMapClick
ポイントモードの時、マップをクリックしたとき実行させる
ロジックの入れ子です。
*/
/************************************************************/
_OnMapClick : function()
{
},
/************************************************************/
/*
(method) IsPoint
オブジェクトがkaXmlPointオブジェクトかどうかを判定します。
*/
/************************************************************/
IsPoint : function(o)
{
return o.constructor.toString().match(/^function\skaXmlPoint\(/g) != null;
},
/************************************************************/
/*
(method) DisplayNumberBaloon
オブジェクト番号を表示します。
*/
/************************************************************/
DisplayNumberBaloon : function(object, number)
{
var pp = (this.IsPoint(object)) ? object :
(object.StartPoint) ? object.StartPoint :null;
if(pp == null) return;
var p = ICTMAP.myXmlOverlay.addNewPoint(pp.sid + "___num_baloon___", pp.geox, pp.geoy);
if(p.div)
{
var rdiv = document.getElementById(p.div.id + "___baloon___");
if(rdiv)
{
rdiv.parentNode.removeChild(rdiv);
}
var div = document.createElement("div");
div.setAttribute("id", p.div.id + "___baloon___");
div.style.width = "30px";
div.style.height = "40px";
div.style.top = "-38px";
div.style.left = "-5px";
div.style.position="absolute";
var self = this;
div.onclick = function(e)
{
if(!self.IsPoint(object))
{
var g = ICTMAP.IctMap.Tools.ToGeometory(e);
self.OnToolClick.apply(self, [object, KAMAP_MAP_CLICKED, g]);
}
else
{
self.OnPointClick.apply(self, [object]);
}
};
div.style.cursor = "pointer";
var img = document.createElement("img");
img.src = ICTMAP_URL + "common/images2/number_label.gif";
img.width = 30;
img.height = 40;
div.appendChild(img);
div.innerHTML += " "
/*
div.style.backgroundImage="url('" + ICTMAP_URL + "common/images2/number_label.gif')";
div.style.backgroundRepeat = "no-repeat";
div.style.paddingTop = "3px";
div.style.paddingLeft = "3px";
div.style.zIndex = "999";
*/
var cdiv = document.createElement("div");
cdiv.style.position = "absolute";
cdiv.style.top = "4px";
cdiv.style.left = "2px";
cdiv.style.width = "22px";
cdiv.style.textAlign = "center";
cdiv.innerHTML = number;
div.appendChild(cdiv);
p.div.appendChild(div);
this.NumberBaloonCollection.push(pp.sid + "___num_baloon___");
}
},
/************************************************************/
/*
(method) CloseNumberBaloon
オブジェクト番号の表示を閉じます。
*/
/************************************************************/
CloseNumberBaloon : function(object)
{
if(typeof object == "undefined" || arguments.length == 0)
{
for(var i=0; i 2 && Math.abs(s_top - d_top) > 2)
{
nameList.style.left = o.div.offsetLeft + "px";
nameList.style.top = o.div.offsetTop + "px";
this._RemoveNameObjects();
}
o.div.canvas.appendChild(nameList);
}
if(nameList.style.display == "none")
{
nameList.innerHTML = "";
nameList.style.display = "block";
}
var a = $(p.sid + suffix);
if(typeof a == "undefined" || a == null)
{
a = document.createElement("a");
a.setAttribute("id", p.sid + suffix);
a.href = "#";
var callback = (this.IsPoint(o)) ? this.OnPointClick : this.OnToolClick;
var g = {x:p.geox, y:p.geoy};
a.onclick = function()
{
clearOverlaysymbolhtml();
callback.apply(self, [o, KAMAP_MAP_CLICKED, g]);
return false;
};
if(name)
{
a.innerHTML = name;
nameList.appendChild(a);
}
}
},
/************************************************************/
/*
(private method) _RemoveNameList
名前リストからの削除予約を行います。
削除は、レイヤー位置が変更になったときに実行されます。
*/
/************************************************************/
_RemoveNameList : function(o)
{
var p = (this.IsPoint(o)) ? o : o.StartPoint;
var suffix = "__title_link";
var a = $(p.sid + suffix);
this._RemoveNameObjectsList.push(a);
},
/************************************************************/
/*
(private method) _RemoveNameObjects
名前リストから削除予約された名前を削除します。
*/
/************************************************************/
_RemoveNameObjects : function()
{
var nameList = getRawObject("namelist");
for(var i=0; i display Small Window
*/
function markerClickPoint(pt1,pt2){
if(typeof google != "undefined"){
if(google.maps){
ICTMAP.points.each(function(pt){
if(pt.pointid==ICTMAP.USERPOINT_PREFIX+pt1+"-"+pt2){
google.maps.event.trigger(pt,'click');
}
$break;
});
}
else
{
var tgtDiv='xmlovr_user_'+pt1+'-'+pt2+'_div';
$(tgtDiv).firstChild.onclick();
}
}else{
var tgtDiv='xmlovr_user_'+pt1+'-'+pt2+'_div';
$(tgtDiv).firstChild.onclick();
}
}
var charset="";
/* ***********************************************************
Example 4-3 (DHTMLapi.js)
"Dynamic HTML:The Definitive Reference"
2nd Edition
by Danny Goodman
Published by O'Reilly & Associates ISBN 1-56592-494-0
http://www.oreilly.com
Copyright 2002 Danny Goodman. All Rights Reserved.
************************************************************ */
// DHTMLapi.js custom API for cross-platform
// object positioning by Danny Goodman (http://www.dannyg.com).
// Release 2.0. Supports NN4, IE, and W3C DOMs.
// Global variables
var isCSS, isW3C, isIE4, isNN4, isIE6CSS, isFIREFOX;
// initialize upon load to let all browsers establish content objects
function initDHTMLAPI() {
if (document.images) {
isCSS = (document.body && document.body.style) ? true : false;
isW3C = (isCSS && document.getElementById) ? true : false;
isIE4 = (isCSS && document.all) ? true : false;
isNN4 = (document.layers) ? true : false;
isIE6CSS = (document.compatMode && document.compatMode.indexOf("CSS1") >= 0) ? true : false;
isFIREFOX = (navigator.userAgent.match(/Firefox/)) ? true : false;
}
}
// set event handler to initialize API
//window.onload = initDHTMLAPI;
// Seek nested NN4 layer from string name
function seekLayer(doc, name) {
var theObj;
for (var i = 0; i < doc.layers.length; i++) {
if (doc.layers[i].name == name) {
theObj = doc.layers[i];
break;
}
// dive into nested layers if necessary
if (doc.layers[i].document.layers.length > 0) {
theObj = seekLayer(document.layers[i].document, name);
}
}
return theObj;
}
// Convert object name string or object reference
// into a valid element object reference
function getRawObject(obj) {
var theObj;
if (typeof obj == "string") {
if (isW3C) {
theObj = document.getElementById(obj);
} else if (isIE4) {
theObj = document.all(obj);
} else if (isNN4) {
theObj = seekLayer(document, obj);
}
} else {
// pass through object reference
theObj = obj;
}
return theObj;
}
// Convert object name string or object reference
// into a valid style (or NN4 layer) reference
function getObject(obj) {
var theObj = getRawObject(obj);
if (theObj && isCSS) {
theObj = theObj.style;
}
return theObj;
}
// Position an object at a specific pixel coordinate
function shiftTo(obj, x, y) {
var theObj = getObject(obj);
if (theObj) {
if (isCSS) {
// equalize incorrect numeric value type
var units = (typeof theObj.left == "string") ? "px" : 0;
theObj.left = x + units;
theObj.top = y + units;
} else if (isNN4) {
theObj.moveTo(x,y)
}
}
}
// Move an object by x and/or y pixels
function shiftBy(obj, deltaX, deltaY) {
var theObj = getObject(obj);
if (theObj) {
if (isCSS) {
// equalize incorrect numeric value type
var units = (typeof theObj.left == "string") ? "px" : 0;
theObj.left = getObjectLeft(obj) + deltaX + units;
theObj.top = getObjectTop(obj) + deltaY + units;
} else if (isNN4) {
theObj.moveBy(deltaX, deltaY);
}
}
}
// Set the z-order of an object
function setZIndex(obj, zOrder) {
var theObj = getObject(obj);
if (theObj) {
theObj.zIndex = zOrder;
}
}
// Set the background color of an object
function setBGColor(obj, color) {
var theObj = getObject(obj);
if (theObj) {
if (isNN4) {
theObj.bgColor = color;
} else if (isCSS) {
theObj.backgroundColor = color;
}
}
}
// Set the visibility of an object to visible
function show(obj) {
var theObj = getObject(obj);
if (theObj) {
theObj.visibility = "visible";
}
}
// Set the visibility of an object to hidden
function hide(obj) {
var theObj = getObject(obj);
if (theObj) {
theObj.visibility = "hidden";
}
}
// Retrieve the x coordinate of a positionable object
function getObjectLeft(obj) {
var elem = getRawObject(obj);
var result = 0;
if (document.defaultView) {
var style = document.defaultView;
var cssDecl = style.getComputedStyle(elem, "");
result = cssDecl.getPropertyValue("left");
} else if (elem.currentStyle) {
result = elem.currentStyle.left;
} else if (elem.style) {
result = elem.style.left;
} else if (isNN4) {
result = elem.left;
}
return parseInt(result);
}
// Retrieve the y coordinate of a positionable object
function getObjectTop(obj) {
var elem = getRawObject(obj);
var result = 0;
if (document.defaultView) {
var style = document.defaultView;
var cssDecl = style.getComputedStyle(elem, "");
result = cssDecl.getPropertyValue("top");
} else if (elem.currentStyle) {
result = elem.currentStyle.top;
} else if (elem.style) {
result = elem.style.top;
} else if (isNN4) {
result = elem.top;
}
return parseInt(result);
}
// Retrieve the rendered width of an element
function getObjectWidth(obj) {
var elem = getRawObject(obj);
var result = 0;
if (elem.offsetWidth) {
result = elem.offsetWidth;
} else if (elem.clip && elem.clip.width) {
result = elem.clip.width;
} else if (elem.style && elem.style.pixelWidth) {
result = elem.style.pixelWidth;
}
return parseInt(result);
}
// Retrieve the rendered height of an element
function getObjectHeight(obj) {
var elem = getRawObject(obj);
var result = 0;
if (elem.offsetHeight) {
result = elem.offsetHeight;
} else if (elem.clip && elem.clip.height) {
result = elem.clip.height;
} else if (elem.style && elem.style.pixelHeight) {
result = elem.style.pixelHeight;
}
return parseInt(result);
}
// Return the available content width space in browser window
function getInsideWindowWidth() {
if (window.innerWidth) {
return window.innerWidth;
} else if (isIE6CSS) {
// measure the html element's clientWidth
return document.body.parentElement.clientWidth;
} else if (document.body && document.body.clientWidth) {
return document.body.clientWidth;
}
return 0;
}
// Return the available content height space in browser window
function getInsideWindowHeight() {
if (window.innerHeight) {
return window.innerHeight;
} else if (isIE6CSS) {
// measure the html element's clientHeight
return document.body.parentElement.clientHeight;
} else if (document.body && document.body.clientHeight) {
return document.body.clientHeight;
}
return 0;
}
var charset="";
/**********************************************************************
*
* $Id: xhr.js,v 1.8 2006/02/07 03:19:55 pspencer Exp $
*
* purpose: a simple cross-browser XmlHttpRequest interface that adds
* support for multiple, concurrent requests
*
* author: Paul Spencer (pspencer@dmsolutions.ca)
*
* TODO:
* - reponse only contains responseText, should contain response so
* access to reponseXML is possible if we ever want to implement
* xml stuff (i.e. real AJAX)
*
**********************************************************************
*
* Copyright (c) 2005, DM Solutions Group Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
**********************************************************************/
/* to make an asynchronous call to the server, execute the call() function
* with the URL to the script to be executed. The second and third
* parameters to call() define object and method to call when the server
* returns its response ... if the second parameter is null, third is
* just a function. If second is an object, then the third is a method
* of that instance.
*
* There is an optional fourth parameter to issue the request as a POST
* to the server. This is important in some browsers due to limited
* URL length.
*
* The callback function is called when the request completes. There is
* currently no callback for errors so they just silently fail if the
* server side script dies. The callback function is passed a single
* parameter, the text output of the server side script. In ka-Map, this
* text is typically some javascript to eval().
*/
var aXmlHttp = new Array();
var aXmlResponse = new Array();
function xmlResult()
{
for(var i=0;i url
// o -> object (can be null) to invoke function on
// f -> callback function
// p -> optional argument to specify POST
function call(u,o,f)
{
var method = "GET";
var dat;
if (arguments.length==4){
method = "POST";
tmp = u.split(/\?/);
u = tmp[0];
dat = tmp[1];
}
var idx = aXmlHttp.length;
for(var i=0; i
*
* 2) add a element to your page to contain the legend. The div must
* have a unique id:
*
*
*
* 3) create a new instance of kaLegend and pass it the id of the div:
*
* myKaLegend = new kaLegend( 'legend' );
*
* and that's it :)
*
*****************************************************************************/
/******************************************************************************
* kaLegend
*
* internal class to handle the legend.
*
* oKaMap - the ka-Map object to attach to.
* szID - string, the id of a div that will contain the legend
* bStatic - boolean, true to use static legends, false to use dynamic legends
*
*****************************************************************************/
function kaLegend(oKaMap, szID, bStatic, options) {
this.kaMap = oKaMap;
this.domObj = this.kaMap.getRawObject(szID);
this.type = (bStatic)?'static':'dynamic';
this.expanders = [];
this.queryCBs = [];
this.urlBase = this.kaMap.server;
this.urlBase += (this.urlBase!=''&&this.urlBase.substring(-1)!='/')?'':'/';
this.showQueryCBs = true;
if (this.type == 'static') {
this.domImg = document.createElement( 'img' );
this.domImg.src = this.kaMap.aPixel.src;
this.domObj.appendChild( this.domImg );
} else {
this.domObj.innerHTML = ' ';
}
this.showVisibilityControl = true;
this.showQueryControl = true;
this.showOpacityControl = true;
this.showOrderControl = true;
if (typeof options != 'undefined') {
this.showVisibilityControl = typeof options.visibility != 'undefined' ? options.visibility : true;
this.showQueryControl = typeof options.query != 'undefined' ? options.query : true;
this.showOpacityControl = typeof options.opacity != 'undefined' ? options.opacity : true;
this.showOrderControl = typeof options.order != 'undefined' ? options.order : true;
}
this.kaMap.registerForEvent( KAMAP_SCALE_CHANGED, this, this.update );
this.kaMap.registerForEvent( KAMAP_MAP_INITIALIZED, this, this.update );
this.kaMap.registerForEvent( KAMAP_LAYERS_CHANGED, this, this.draw );
this.kaMap.registerForEvent( KAMAP_LAYER_STATUS_CHANGED, this, this.update );
};
kaLegend.prototype.update = function(eventID)
{
var url = '';
if (this.type == 'static') {
var newImg = document.createElement('img');
newImg.src = 'legend.phtml?map=' + this.kaMap.currentMap + '&scale='+this.kaMap.getCurrentScale();
this.domObj.replaceChild(newImg, this.domImg);
this.domImg = newImg;
} else {
if (eventID == KAMAP_MAP_INITIALIZED) {
while(this.domObj.childNodes.length > 0) {
this.domObj.removeChild(this.domObj.childNodes[0]);
} this.draw();
} else if (eventID == KAMAP_SCALE_CHANGED) {
var oMap = this.kaMap.getCurrentMap();
var aLayers = oMap.getAllLayers();
var s = this.kaMap.getCurrentScale();
for (var i in aLayers) {
var oLayer = aLayers[i];
var oImg = this.kaMap.getRawObject( 'legendImg_' + oLayer.name);
if (oImg) {
//added by Lorenzo
var oParent = oImg.parentNode;
var tId = oImg.id;
var tVisibility = oImg.visibility;
oParent.removeChild(oImg);
oImg = document.createElement('img');
oImg.id = tId;
oImg.title = tId;
oImg.visibility = tVisibility;
oImg.src = 'legend.phtml?map=' +
this.kaMap.currentMap + '&scale=' + s + '&g=' +
oLayer.name;
oParent.appendChild(oImg);
/*
expander = getRawObject('expander_'+oLayer.name);
expander.expandable = oImg;
expander.expanded = true;
kaLegend_expander.apply( expander );
*/
}
//added by cappu
this.setOnOffLayer(oLayer);
}
} else if (eventID == KAMAP_LAYER_STATUS_CHANGED) {
var layer = arguments[1];
for (var i=0; i
=0;i--) {
if (aLayers[i].kaLegendObj == null) {
this.createLayerHTML( aLayers[i] );
} else {
try{this.domObj.removeChild( aLayers[i].kaLegendObj );}
catch(e){};
}
}
for (var i=(aLayers.length-1);i>=0;i--) {
this.domObj.appendChild( aLayers[i].kaLegendObj );
}
if (this.kaMap.isIE4) {
for(var i=0; i 1) {
//OPACITY IMAGES
if (this.showOpacityControl) {
td = document.createElement('td');
td.width = '19';
img = document.createElement( 'img' );
img.src = 'common/images2/sun_white.png';
img.width = '7';
img.alt = "Decrease layer opacity";
img.title = "Decrease layer opacity";
img.style.cursor ='crosshair';
img.kaLegend = this;
img.oLayer = oLayer;
img.onclick = kaLegend_opacityDown;
td.appendChild( img );
img = document.createElement( 'img' );
img.src = 'common/images2/sun_grey.png';
img.width = '7';
img.style.marginLeft = '2px';
img.alt = "Increase layer opacity";
img.title = "Increase layer opacity";
img.style.cursor ='crosshair';
img.kaLegend = this;
img.oLayer = oLayer;
img.onclick = kaLegend_opacityUp;
td.appendChild( img );
tr.appendChild(td);
}
if (this.showOrderControl) {
//SHIFT LAYERS UP DOWN
td = document.createElement('td');
td.width = '10';
td.style.padding = '1px';
img = document.createElement( 'img' );
img.src = 'common/images2/arrow_up.png';
img.width = '10';
img.height = '8';
img.style.marginBottom = '2px';
img.alt = "Shift Layer Up";
img.title = "Shift Layer Up";
img.style.cursor ='crosshair';
img.kaLegend = this;
img.oLayer = oLayer;
img.myDiv = d;
img.onclick = kaLegend_moveLayerUp;
td.appendChild( img );
img = document.createElement( 'img' );
img.src = 'common/images2/arrow_down.png';
img.width = '10';
img.height = '8';
img.alt = "Shift Layer Down";
img.title = "Shift Layer Down";
img.style.cursor ='crosshair';
img.kaLegend = this;
img.oLayer = oLayer;
img.myDiv = d;
img.onclick = kaLegend_moveLayerDown;
td.appendChild( img );
tr.appendChild(td);
}
}
if (this.showQueryControl) {
//layer queryable images
td = document.createElement('td');
td.width = '14';
img = document.createElement( 'img' );
img.width = '14';
img.height = '14';
if (oLayer.queryable) {
if (oLayer.isQueryable()) {
img.src = 'common/images2/icon_query_on.png';
} else {
img.src = 'common/images2/icon_query_off.png';
}
img.onmouseover = kaLegend_queryOnMouseOver;
img.onmouseout = kaLegend_queryOnMouseOut;
img.onclick = kaLegend_queryOnClick;
img.oLayer = oLayer;
} else {
img.src = 'common/images2/icon_query_x.png';
}
td = document.createElement( 'td' );
td.appendChild(img);
td.width = '16';
tr.appendChild(td);
}
td = document.createElement( 'td' );
td.innerHTML = oLayer.name2;
tr.appendChild(td);
tb.appendChild(tr);
t.appendChild( tb );
d.appendChild(t);
//img = document.createElement( 'img' );
//img.id = 'legendImg_' + oLayer.name;
//img.src = this.urlBase + 'legend.phtml?map='+this.kaMap.currentMap+'&scale='+this.kaMap.getCurrentScale()+'&g='+oLayer.name;
/*modificato da kappu, nel cvs dimentica di aggiungere immagine */
//d.appendChild(img);
//expander.expandable = img; sakai
oLayer.kaLegendObj = d;
//kaLegend_expander.apply( expander ); sakai
//adedd by cappu
this.setOnOffLayer(oLayer,oLayer.isVisible); //prototype.jsを入れたらエラーになるのでコメントアウト
};
function kaLegend_toggleLayerQueryable() {
this.kaLegend.kaMap.setLayerQueryable( this.value, this.checked );
};
function kaLegend_queryOnMouseOver() {
if (this.oLayer.queryable) {
this.src = 'common/images2/icon_query_over.png';
}
};
function kaLegend_queryOnMouseOut() {
if (this.oLayer.queryable) {
if (this.oLayer.isQueryable()) {
this.src = 'common/images2/icon_query_on.png';
} else {
this.src = 'common/images2/icon_query_off.png';
}
}
};
function kaLegend_queryOnClick() {
if (this.oLayer.queryable) {
if (this.oLayer.isQueryable()) {
this.oLayer.setQueryable( false );
this.src = 'common/images2/icon_query_off.png';
} else {
this.oLayer.setQueryable( true );
this.src = 'common/images2/icon_query_on.png';
}
}
};
function kaLegend_toggleLayerVisibility() {
this.kaLegend.kaMap.setLayerVisibility( this.value, this.checked );
}
function kaLegend_expander() {
this.expanded = !this.expanded;
this.src = (this.expanded)?'common/images2/collapse.png':'common/images2/expand.png';
this.expandable.style.display = (this.expanded)?'block':'none';
};
function kaLegend_expandAll() {
var kaLeg = this.kaLegend;
for (var i=0; i= 0) ? true : false;
}
this.domObj = this.getRawObject( szID );
this.domObj.style.overflow = 'hidden';
this.hideLayersOnMove = false;
//if true layer not checked are loaded if false aren't loaded
this.loadUnchecked=false;
/**
* initialization states
* 0 - not initialized
* 1 - initializing
* 2 - initialized
*/
this.initializationState = 0;
//track mouse down events
this.bMouseDown = false;
//track last recorded mouse position
this.lastx = 0;
this.lasty = 0;
//keep a reference to the inside layer since we use it a lot
this.theInsideLayer = null;
//viewport width and height are used in many calculations
this.viewportWidth = this.getObjectWidth(this.domObj);
this.viewportHeight = this.getObjectHeight(this.domObj);
//track amount the inside layer has moved to help in wrapping images
this.xOffset = 0;
this.yOffset = 0;
//track current origin offset value
this.xOrigin = 0;
this.yOrigin = 0;
//the name of the current map
this.currentMap = '';
//the current width and height in tiles
this.nWide = 0;
this.nHigh = 0;
//current top and left are tracked when the map moves
//to start the map at some offset, these would be set to
//the appropriate pixel value.
this.nCurrentTop = 0; //null;
this.nCurrentLeft = 0; //null;
//keep a live reference to aPixel to help with caching problems - hish
this.aPixel = new Image(1,1);
this.aPixel.src = ICTMAP_URL + 'common/images2/a_pixel.gif';
//error stack for tracking images that have failed to load
this.imgErrors = new Array();
//an array of available maps
this.aMaps = new Array();
//tile size and buffer size determine how many tiles to create
this.tileWidth = null;
this.tileHeight = null;
this.nBuffer = 1;
this.baseURL = '';
//size of a pixel, geographically - assumed to be square
this.cellSize = null;
//image id counter - helps with reloading failed images
this.gImageID = 0;
//event manager
this.eventManager = new _eventManager();
//slider stuff
this.as=slideid=null;
this.accelerationFactor=1;
this.pixelsPerStep = 30;
this.timePerStep = 25;
//this is a convenience to allow redirecting the client code to a server
//other than the one that this file was loaded from. This may not
//work depending on security settings, except for loading tiles since
//those come directly from a php script instead of an XmlHttpRequest.
//
//by default, if this is empty, it loads from the same site as the
//page loaded from. If set, it should be a full http:// reference to the
//directory in which init.phtml, tile.phtml and the other scripts are located.
this.server = '';
//similarly, this is the global initialization script called once per page
//load ... the result of this script tell the client what other scripts
//are used for the other functions
if(initFile != null){
this.init = initFile;
}else{
this.init = "init.phtml";
}
//初期設定内容
//API化するにあたってクロスドメイン対応
this.initSettings = initSettings;
//these are the values that need to be initialized by the init script
this.tileURL = null;
this.aObjects = [];
this.aCanvases = [];
this.layersHidden = false;
this.aTools = [];
this.aInfoTools = [];
//サブマップ
this.kaKeymap = null;
// 自動で移動フラグ sakai
this.automove = false;
// 基本アイコン表示フラグ デフォルト非表示
this.dspLandmark = false;
//アイコンクリックオブジェクト
this.iconClick = new Array();
this.iconMouseOver = new Array();
this.iconMouseOut = new Array();
//標準ポイントプリフィックス
this.BASEPOINT_PREFIX = "kp";
//ユーザポイントプリフィックス
this.USERPOINT_PREFIX = "user_";
/* register the known events */
for (var i=0; i 0) {
theObj = this.seekLayer(document.layers[i].document, name);
}
}
return theObj;
};
// Convert object name string or object reference
// into a valid element object reference
kaMap.prototype.getRawObject = function(obj) {
var theObj;
if (typeof obj == "string") {
if (this.isW3C) {
theObj = document.getElementById(obj);
} else if (this.isIE4) {
theObj = document.all(obj);
} else if (this.isNN4) {
theObj = seekLayer(document, obj);
}
} else {
// pass through object reference
theObj = obj;
}
return theObj;
};
// Convert object name string or object reference
// into a valid style (or NN4 layer) reference
kaMap.prototype.getObject = function(obj) {
var theObj = this.getRawObject(obj);
if (theObj && this.isCSS) {
theObj = theObj.style;
}
return theObj;
};
// Retrieve the rendered width of an element
kaMap.prototype.getObjectWidth = function(obj) {
var elem = this.getRawObject(obj);
var result = 0;
if (elem.offsetWidth) {
result = elem.offsetWidth;
} else if (elem.clip && elem.clip.width) {
result = elem.clip.width;
} else if (elem.style && elem.style.pixelWidth) {
result = elem.style.pixelWidth;
}
return parseInt(result);
};
// Retrieve the rendered height of an element
kaMap.prototype.getObjectHeight = function(obj) {
var elem = this.getRawObject(obj);
var result = 0;
if (elem.offsetHeight) {
result = elem.offsetHeight;
} else if (elem.clip && elem.clip.height) {
result = elem.clip.height;
} else if (elem.style && elem.style.pixelHeight) {
result = elem.style.pixelHeight;
}
return parseInt(result);
};
/**
* kaMap.zoomTo( lon, lat [, scale] )
*
* zoom to some geographic point (in current projection) and optionally scale
*
* lon - the x coordinate to zoom to
* lat - the y coordinate to zoom to
* scale - optional. The scale to use
*/
kaMap.prototype.zoomTo = function( cgX, cgY ) {
getRawObject("pointinfo").style.visibility='hidden'; // sakai
var oMap = this.getCurrentMap();
var inchesPerUnit = new Array(1, 12, 63360.0, 39.3701, 39370.1, 4374754);
var newScale;
var bScaleChanged = false;
if (arguments.length == 3) {
newScale = arguments[2];
bScaleChanged = (newScale != this.getCurrentScale())
} else {
newScale = this.getCurrentScale();
}
var bZoomTo = true;
if (!bScaleChanged) {
var extents = this.getGeoExtents();
if (cgX >= extents[0] && cgX <= extents[2] &&
cgY >= extents[1] && cgY <= extents[3]) {
var cx = (extents[0]+extents[2])/2;
var cy = (extents[1]+extents[3])/2;
var dx = (cx - cgX)/this.cellSize;
var dy = (cgY - cy)/this.cellSize;
this.slideBy(dx,dy);
bZoomTo = false;
}
}
if (bZoomTo) {
this.cellSize = newScale/(oMap.resolution * inchesPerUnit[oMap.units]);
var nFactor = oMap.zoomToScale( newScale );
this.setMapLayers();
var cpX = cgX / this.cellSize;
var cpY = cgY / this.cellSize;
var vpLeft = Math.round(cpX - this.viewportWidth/2);
var vpTop = Math.round(cpY + this.viewportHeight/2);
//figure out which tile the center point lies on
var cTileX = Math.floor(cpX/this.tileWidth)*this.tileWidth;
var cTileY = Math.floor(cpY/this.tileHeight)*this.tileHeight;
//figure out how many tiles left and up we need to move to lay out from
//the top left and have the top/left image off screen (or partially)
var nTilesLeft = Math.ceil(this.viewportWidth/(2*this.tileWidth))*this.tileWidth;
var nTilesUp = Math.ceil(this.viewportHeight/(2*this.tileHeight))*this.tileHeight;
this.nCurrentLeft = cTileX - nTilesLeft;
this.nCurrentTop = -1*(cTileY + nTilesUp);
this.xOrigin = this.nCurrentLeft;
this.yOrigin = this.nCurrentTop;
this.theInsideLayer.style.left = -1*(vpLeft - this.xOrigin) + "px";
this.theInsideLayer.style.top = (vpTop + this.yOrigin) + "px";
var layers = oMap.getLayers();
for( var k=0; k= oMap.aScales[i]) {
break;
}
newScale = oMap.aScales[i];
}
//now newScale has our new scale size
this.cellSize = newScale/(oMap.resolution * inchesPerUnit[oMap.units]);
var nFactor = oMap.zoomToScale( newScale );
this.setMapLayers();
var cpX = cgX / this.cellSize;
var cpY = cgY / this.cellSize;
var vpLeft = Math.round(cpX - this.viewportWidth/2);
var vpTop = Math.round(cpY + this.viewportHeight/2);
//figure out which tile the center point lies on
var cTileX = Math.floor(cpX/this.tileWidth)*this.tileWidth;
var cTileY = Math.floor(cpY/this.tileHeight)*this.tileHeight;
//figure out how many tiles left and up we need to move to lay out from
//the top left and have the top/left image off screen (or partially)
var nTilesLeft = Math.ceil(this.viewportWidth/(2*this.tileWidth))*this.tileWidth;
var nTilesUp = Math.ceil(this.viewportHeight/(2*this.tileHeight))*this.tileHeight;
this.nCurrentLeft = cTileX - nTilesLeft;
this.nCurrentTop = -1*(cTileY + nTilesUp);
this.xOrigin = this.nCurrentLeft;
this.yOrigin = this.nCurrentTop;
this.theInsideLayer.style.left = -1*(vpLeft - this.xOrigin) + "px";
this.theInsideLayer.style.top = (vpTop + this.yOrigin) + "px";
var layers = oMap.getLayers();
for( var k=0; k 2 && arguments[2] != '') {
this.initializeCallback(this.initSettings,arguments[2]);
}else{
this.initializeCallback(this.initSettings);
}
}else{
/* call initialization script on the server */
var szURL = this.server+this.init;
var sep = (this.init.indexOf("?") == -1) ? "?" : "&";
if (arguments.length > 0 && arguments[0] != '') {
szURL = szURL + sep + "map="+ arguments[0];
sep = "&";
}
if (arguments.length > 1 && arguments[1] != '') {
szURL = szURL + sep + "extents="+ arguments[1];
sep = "&";
}
if (arguments.length > 2 && arguments[2] != '') {
szURL = szURL + sep + "centerPoint="+ arguments[2];
sep = "&";
}
call(szURL, this, this.initializeCallback);
}
return true;
};
/**
* hidden function on callback from init.phtml
*/
kaMap.prototype.initializeCallback = function( szInit ) {
// szInit contains /*init*/ if it worked, or some php error otherwise
if (szInit.substr(0, 1) != "/") {
this.triggerEvent( KAMAP_ERROR, 'ERROR: ka-Map! initialization '+
'failed on the server. Message returned was:\n' +
szInit);
return false;
}
eval(szInit);
if(arguments.length > 1 && arguments[1] != null){
var tmpArray = arguments[1].split(",");
this.zoomTo(tmpArray[0], tmpArray[1], tmpArray[2]);
}
this.triggerEvent( KAMAP_INITIALIZED );
this.initializationState = 2;
};
/**
* kaMap.setBackgroundColor( color )
*
* call this to set a background color for the inside layer. This color
* shows through any transparent areas of the map. This is primarily
* intended to be used by the initializeMap callback function to set the
* background to the background color in the map file.
*
* color: string, a valid HTML color string
*
* returns true;
*/
kaMap.prototype.setBackgroundColor = function( color ) {
this.domObj.style.backgroundColor = color;
return true;
};
/**
* hidden method of kaMap to initialize all the various layers needed by
* kaMap to draw and move the map image.
*/
kaMap.prototype.createLayers = function() {
this.theInsideLayer = document.createElement('div');
this.theInsideLayer.id = 'theInsideLayer';
this.theInsideLayer.style.position = 'absolute';
this.theInsideLayer.style.left = '0px';
this.theInsideLayer.style.top = '0px';
this.theInsideLayer.style.zIndex = '1';
this.theInsideLayer.kaMap = this;
if (this.currentTool) {
this.theInsideLayer.style.cursor = this.currentTool.cursor;
}
this.domObj.appendChild(this.theInsideLayer);
this.domObj.kaMap = this;
this.theInsideLayer.onmousedown = kaMap_onmousedown;
this.theInsideLayer.onmouseup = kaMap_onmouseup;
this.theInsideLayer.onmousemove = kaMap_onmousemove;
this.theInsideLayer.onmouseover = kaMap_onmouseover;
this.domObj.onmouseout = kaMap_onmouseout;
this.theInsideLayer.onkeypress = kaMap_onkeypress;
this.theInsideLayer.ondblclick = kaMap_ondblclick;
this.theInsideLayer.oncontextmenu = kaMap_oncontextmenu;
/* マウスホイールでの拡大縮小をしないように *070615upd/
/* this.theInsideLayer.onmousewheel = kaMap_onmousewheel;*/
if (window.addEventListener &&
navigator.product && navigator.product == "Gecko") {
/* this.domObj.addEventListener( "DOMMouseScroll", kaMap_onmousewheel, false );*/
}
//this is to prevent problems in IE
this.theInsideLayer.ondragstart = new Function([], 'var e=e?e:event;e.cancelBubble=true;e.returnValue=false;return false;');
};
/**
* internal function
* update the layer URLs based on their current positions
*/
kaMap.prototype.initializeLayers = function(nFactor) {
var deltaMouseX = this.nCurrentLeft + safeParseInt(this.theInsideLayer.style.left) - this.xOrigin;
var deltaMouseY = this.nCurrentTop + safeParseInt(this.theInsideLayer.style.top) - this.yOrigin;
var vpTop = this.nCurrentTop - deltaMouseY;
var vpLeft = this.nCurrentLeft - deltaMouseX;
var vpCenterX = vpLeft + this.viewportWidth/2;
var vpCenterY = vpTop + this.viewportHeight/2;
var currentTileX = Math.floor(vpCenterX/this.tileWidth)*this.tileWidth;
var currentTileY = Math.floor(vpCenterY/this.tileHeight)*this.tileHeight;
var tileDeltaX = currentTileX - this.nCurrentLeft;
var tileDeltaY = currentTileY - this.nCurrentTop;
var newVpCenterX = vpCenterX * nFactor;
var newVpCenterY = vpCenterY * nFactor;
var newTileX = Math.floor(newVpCenterX/this.tileWidth) * this.tileWidth;
var newTileY = Math.floor(newVpCenterY/this.tileHeight) * this.tileHeight;
var newCurrentLeft = newTileX - tileDeltaX;
var newCurrentTop = newTileY - tileDeltaY;
this.nCurrentLeft = newCurrentLeft;
this.nCurrentTop = newCurrentTop;
var newTilLeft = -newVpCenterX + this.viewportWidth/2;
var newTilTop = -newVpCenterY + this.viewportHeight/2;
var xOldOrigin = this.xOrigin;
var yOldOrigin = this.yOrigin;
this.xOrigin = this.nCurrentLeft;
this.yOrigin = this.nCurrentTop;
this.theInsideLayer.style.left = (newTilLeft + this.xOrigin) + "px";
this.theInsideLayer.style.top = (newTilTop + this.yOrigin) + "px";
var layers = this.aMaps[this.currentMap].getLayers();
for( var k=0; k newHigh && newHigh > 3) {
this.removeRow();
}
while (this.nWide < newWide) {
this.appendColumn();
}
while (this.nWide > newWide && newWide > 3) {
this.removeColumn();
}
//create image don't call layer.set tile so i need to do that!
var map = this.getCurrentMap();
var layers =map.getLayers();
for(i=0;i=0; j--) {
var top = this.nCurrentTop + (j * this.tileHeight);
var left = this.nCurrentLeft + (this.nWide * this.tileWidth);
var img = this.createImage( top, left, layers[i] );
//hack around IE problem with clipping layers when a filter is
//active
if (this.isIE4) {
img.style.filter = "Alpha(opacity="+layers[i].opacity+")";
}
if (j < this.nHigh-1) {
obj.insertBefore(img, obj.childNodes[((j+1)*this.nWide)]);
} else {
obj.appendChild(img);
}
}
}
this.nWide = this.nWide + 1;
};
/**
* internal function to remove a column of images to each of the layers
*
* this function is used when the viewport is resized
* modified by cappu can take a single layer as input
*/
kaMap.prototype.removeColumn = function(layer) {
if (this.nWide < 3) {
return;
}
var layers = null;
if(arguments.length==1) {
layers = Array(layer);
} else {
layers = this.aMaps[this.currentMap].getLayers();
}
for( var i=0; i= 0; j--) {
var img = d.childNodes[((j+1)*this.nWide)-1];
d.removeChild( img );
//attempt to prevent memory leaks
img.onload = null;
img.onerror = null;
}
}
this.nWide = this.nWide - 1;
};
/**
* internal function to remove a row of images to each of the layers
*
* this function is used when the viewport is resized
* modified by cappu can take a single layer as input
*/
kaMap.prototype.removeRow = function(layer) {
if (this.nHigh < 3) {
return;
}
var layers = null;
if(arguments.length==1) {
layers = Array(layer);
} else {
layers = this.aMaps[this.currentMap].getLayers();
}
for( var i=0; i= 0; j--) {
var img = d.childNodes[((this.nHigh-1)*this.nWide)+j];
d.removeChild( img );
//attempt to prevent memory leaks
img.onload = null;
img.onerror = null;
}
}
this.nHigh = this.nHigh - 1;
};
kaMap.prototype.hideLayers = function() {
if (!this.hideLayersOnMove) {
return;
}
if (this.layersHidden) {
return;
}
var layers = this.aMaps[this.currentMap].getLayers();
for( var i=0; iabsY?absX:absY;
var steps = Math.floor(distance/this.pixelsPerStep);
var dx = dy = 0;
if (steps > 0) {
dx = (x)/(steps*this.pixelsPerStep);
dy = (y)/(steps*this.pixelsPerStep);
}
var remainderX = x - dx*steps*this.pixelsPerStep;
var remainderY = y - dy*steps*this.pixelsPerStep;
var px=py=0;
var curspeed=this.accelerationFactor;
var i=0;
while(i0) {
px+=this.as[i-1][0];
py+=this.as[i-1][1];
}
var cx = px+Math.round(dx*this.pixelsPerStep);
var cy = py+Math.round(dy*this.pixelsPerStep);
this.as[i]=new Array(cx-px,cy-py);
i++;
}
if (remainderX != 0 || remainderY != 0) {
this.as[i] = [remainderX, remainderY];
}
this.hideLayers();
this.slideid=goQueueManager.enqueue(this.timePerStep,this,this.slide,[0]);
};
/**
* handle individual movement within a slide
*/
kaMap.prototype.slide = function(pos) {
if (pos>=this.as.length) {
this.as=slideid=null;
this.showLayers();
this.triggerEvent( KAMAP_EXTENTS_CHANGED, this.getGeoExtents() );
return;
}
this.moveBy( this.as[pos][0], this.as[pos][1] );
pos ++;
this.slideid=goQueueManager.enqueue(this.timePerStep,this,this.slide,[ pos]);
};
/**
* internal function to handle various events that are passed to the
* current tool
*/
kaMap_onkeypress = function( e ) {
if (this.kaMap.currentTool) {
this.kaMap.currentTool.onkeypress( e );
}
if (this.kaMap.aInfoTools.length > 0) {
for (var i=0; i 0) {
for (var i=0; i 0) {
for (var i=0; i 0) {
for (var i=0; i 0) {
for (var i=0; i 0) {
for (var i=0; i 0) {
for (var i=0; i 0) {
this.wrapR2L();
bWrapped = true;
}
while (this.xOffset < -(this.nBuffer*this.tileWidth)) {
this.wrapL2R();
bWrapped = true;
}
while (this.yOffset > -(this.nBuffer*this.tileHeight)) {
this.wrapB2T();
bWrapped = true;
}
while (this.yOffset < -(2*this.nBuffer*this.tileHeight)) {
this.wrapT2B();
bWrapped = true;
}
var layer = this.aMaps[this.currentMap].getLayers()[0];
if (layer) {
var img = layer.domObj.childNodes[0].style;
this.nCurrentTop = safeParseInt(img.top) + this.yOrigin;
this.nCurrentLeft = safeParseInt(img.left) + this.xOrigin;
}
if (bWrapped) {
this.triggerEvent( KAMAP_METAEXTENTS_CHANGED, this.getMetaExtents() );
}
};
/**
* kaMap.checkMaxExtents()
*
* For maps with maxExtent set, this function adjusts the position of
* theInsideLayer so it never shows more than the maximum extent specified
* in the mapfile. Called from kaMap.checkWrap() since that is called
* with all movement of theInsideLayer
*
* Added by tschaub
*/
kaMap.prototype.checkMaxExtents = function() {
var maxExtents = this.getCurrentMap().maxExtents;
if (maxExtents.length == 4) {
if ((maxExtents[0] >= maxExtents[2]) || (maxExtents[1] >= maxExtents[3])) {
// fail silently
return false;
}
var geoExtents = this.getGeoExtents();
var hPixelAdjustment = 0;
var vPixelAdjustment = 0;
// check left and right
if (geoExtents[0] < maxExtents[0]) {
// extra on right
hPixelAdjustment = Math.round((maxExtents[0] - geoExtents[0]) / this.cellSize);
}
if (geoExtents[2] > maxExtents[2]) {
// extra on left
if(hPixelAdjustment != 0)
{
// if both left and right are over, split the difference
hPixelAdjustment += Math.round((maxExtents[2] - geoExtents[2]) / this.cellSize);
hPixelAdjustment /= 2;
} else {
hPixelAdjustment += Math.round((maxExtents[2] - geoExtents[2]) / this.cellSize);
}
}
// check if horizontal adjustment is needed
if(hPixelAdjustment != 0) {
this.theInsideLayer.style.left = (safeParseInt(this.theInsideLayer.style.left) - hPixelAdjustment) + 'px';
}
// check top and bottom - both can not be corrected
if(geoExtents[1] < maxExtents[1]) {
// extra on bottom
vPixelAdjustment = Math.round((maxExtents[1] - geoExtents[1]) / this.cellSize);
}
if(geoExtents[3] > maxExtents[3]) {
// extra on top
if(vPixelAdjustment != 0) {
// if both top and bottom are over, split the difference
vPixelAdjustment += Math.round((maxExtents[3] - geoExtents[3]) / this.cellSize);
vPixelAdjustment /= 2;
} else {
vPixelAdjustment = Math.round((maxExtents[3] - geoExtents[3]) / this.cellSize);
}
}
if(vPixelAdjustment != 0) {
this.theInsideLayer.style.top = (safeParseInt(this.theInsideLayer.style.top) + vPixelAdjustment) + 'px';
}
}
};
/**
* internal function to reuse extra images
* take last image from each row and put it at the beginning
*/
kaMap.prototype.wrapR2L = function() {
this.xOffset = this.xOffset - (this.nBuffer * this.tileWidth);
var layers = this.aMaps[this.currentMap].getLayers();
for( var k=0; k=0; i-- ) {
if (this.theInsideLayer.childNodes[i].className == 'mapLayer') {
this.theInsideLayer.childNodes[i].appended=false;
this.theInsideLayer.removeChild(this.theInsideLayer.childNodes[i]); }
}
//now check layer and create or append
layers=oMap.getLayers(); //get only visible and checked layers
for( var i=0; i newHigh) {
this.removeRow(group);
}
while (this.nWide < newWide) {
this.appendColumn(group);
}
while (this.nWide > newWide) {
this.removeColumn(group);
}
return true;
};
kaMap.prototype.createMapLayer = function( id ) {
var d = document.createElement( 'div' );
d.id = id;
d.className = 'mapLayer';
d.style.position = 'absolute';
d.style.visibility = 'visible';
d.style.left = '0px';
d.style.top = '0px';
d.style.width= '3000px';
d.style.height = '3000px';
d.appended= false;//added by cappu
return d;
};
//modified by cappu
kaMap.prototype.addMapLayer = function( l ) {
var map = this.getCurrentMap();
map.addLayer(l);
this.setMapLayers();
this.paintLayer(l);
this.triggerEvent( KAMAP_LAYERS_CHANGED, this.currentMap );
};
//added by cappu
kaMap.prototype.removeMapLayer = function( id ) {
var map = this.getCurrentMap();
var layer = map.getLayer(id);
if (!layer) {
return false;
}
if (map.removeLayer ( map.getLayer(id) )) {
this.setMapLayers();
this.triggerEvent( KAMAP_LAYERS_CHANGED, this.currentMap );
}
};
kaMap.prototype.getCenter = function() {
var deltaMouseX = this.nCurrentLeft - this.xOrigin + safeParseInt(this.theInsideLayer.style.left);
var deltaMouseY = this.nCurrentTop - this.yOrigin + safeParseInt(this.theInsideLayer.style.top);
var vpTop = this.nCurrentTop - deltaMouseY;
var vpLeft = this.nCurrentLeft - deltaMouseX;
var vpCenterX = vpLeft + this.viewportWidth/2;
var vpCenterY = vpTop + this.viewportHeight/2;
return new Array( vpCenterX, vpCenterY );
};
/**
* kaMap.getGeoExtents()
*
* returns an array of geographic extents for the current view in the form
* (inx, miny, maxx, maxy)
*/
kaMap.prototype.getGeoExtents = function() {
var minx = -1*(safeParseInt(this.theInsideLayer.style.left) - this.xOrigin) * this.cellSize;
var maxx = minx + this.viewportWidth * this.cellSize;
var maxy= (safeParseInt(this.theInsideLayer.style.top) - this.yOrigin) * this.cellSize;
var miny= maxy - this.viewportHeight * this.cellSize;
return [minx,miny,maxx,maxy];
};
/**
* kaMap.getMetaExtents()
*
* returns an array of geographic extents for the loaded tiles in the form
* (minx, miny, maxx, maxy)
*/
kaMap.prototype.getMetaExtents = function() {
//use current extents if no layers visible
var result = this.getGeoExtents();
var oMap = this.getCurrentMap();
layers=oMap.getLayers();
for( var i=0; i 0) {
nZoomFactor = this.aScales[this.currentScale]/this.aScales[this.currentScale-1];
this.currentScale = this.currentScale - 1;
}
return nZoomFactor;
};
_map.prototype.zoomToScale = function( scale ) {
var nZoomFactor = 1;
for (var i=0; i 0) {
goQueueManager.enqueue( this.refreshInterval*1000, this, this.redraw );
}
};
_layer.prototype.isQueryable = function() {
return this.queryState;
};
_layer.prototype.setQueryable = function( bQueryable ) {
if (this.queryable) {
this.queryState = bQueryable;
}
};
//added by cappu check layer visibility at current scale
_layer.prototype.isVisible= function() {
return (this.scales[this._map.currentScale]==1)? true:false;
};
/**
* layer.setOpacity( amount )
*
* set a layer to be semi transparent. Amount is a number between
* 0 and 100 where 0 is fully transparent and 100 is fully opaque
*/
_layer.prototype.setOpacity = function( amount ) {
this.opacity = amount;
if (this.domObj) {
this.domObj.style.opacity = amount/100;
this.domObj.style.mozOpacity = amount/100;
for(var i=0;i 0) {
goQueueManager.enqueue( this.refreshInterval*1000, this, this.redraw );
}
};
/******************************************************************************
* Event Manager class
*
* an internal class for managing generic events. kaMap! uses the event
* manager internally and exposes certain events to the application.
*
* the kaMap class provides wrapper functions that hide this implementation
* useage:
*
* myKaMap.registerForEvent( gnSomeEventID, myObject, myFunction );
* myKaMap.registerForEvent( 'SOME_EVENT', myObject, myFunction );
*
* myKaMap.deregisterForEvent( gnSomeEventID, myObject, myFunction );
* myKaMap.deregisterForEvent( 'SOME_EVENT', myObject, myFunction );
*
* myObject is normally null but can be a javascript object to have myFunction
* executed within the context of an object (becomes 'this' in the function).
*
*****************************************************************************/
function _eventManager( )
{
this.events = [];
this.lastEventID = 0;
}
_eventManager.prototype.registerEventID = function( eventID ) {
var ev = new String(eventID);
if (!this.events[eventID]) {
this.events[eventID] = [];
}
};
_eventManager.prototype.registerForEvent = function(eventID, obj, func) {
var ev = new String(eventID);
this.events[eventID].push( [obj, func] );
};
_eventManager.prototype.deregisterForEvent = function( eventID, obj, func ) {
var ev = new String(eventID);
var bResult = false;
if (!this.events[eventID]) {
return false;
}
for (var i=0;i= 0; i--)
this.domObj.removeChild (this.domObj.childNodes[i]);
this.domObj.style.width = this.imgWidth + "px";
this.domObj.style.height = this.imgHeight + "px";
this.width = this.imgWidth + "px";
this.height = this.imgHeight + "px";
//create an image to hold the keymap
this.domImg = document.createElement( 'img' );
//this.domImg.src = this.imgSrc + '&map='+this.kaMap.currentMap;
this.domImg.src = this.imgSrc + '&map='+this.kaMap.currentMap+"&x="+this.cx+"&y="+this.cy;
this.domImg.width = this.imgWidth;
this.domImg.height = this.imgHeight;
this.domObj.appendChild( this.domImg );
//create a div to track the current extents
this.domExtents = document.createElement( 'div' );
this.domExtents.kaKeymap = this;
this.domExtents.id="keymapDomExtents";
this.domExtents.style.position = 'absolute';
this.domExtents.style.border = '1px solid red';
this.domExtents.style.top = "1px";
this.domExtents.style.left = "1px";
this.domExtents.style.width = "1px";
this.domExtents.style.height = "1px";
this.domExtents.style.backgroundColor = 'transparent';
this.domExtents.style.visibility = 'visible';
this.domObj.appendChild(this.domExtents);
//create a div to allow click/drag of extents for nav
this.domEvent = document.createElement( 'div' );
this.domEvent.kaKeymap=this;
this.domEvent.onmousedown= this.mousedown;
this.domEvent.onmouseup= this.mouseup;
this.domEvent.onmousemove= this.mousemove;
this.domEvent.onmouseout= this.mouseup;
if (this.domEvent.captureEvents) {
this.domEvent.captureEvents(Event.MOUSEDOWN);
this.domEvent.captureEvents(Event.MOUSEUP);
this.domEvent.captureEvents(Event.MOUSEMOVE);
this.domEvent.captureEvents(Event.MOUSEOUT);
}
this.domEvent.style.position = 'absolute';
this.domEvent.id = 'keymapDomEvent';
this.domEvent.style.border = '1px solid red';
this.domEvent.style.top = "1px";
this.domEvent.style.left = "1px";
this.domEvent.style.width = "1px";
this.domEvent.style.height = "1px";
this.domEvent.style.backgroundColor = 'white';
this.domEvent.style.visibility = 'visible';
this.domEvent.style.opacity=0.01;
this.domEvent.style.mozOpacity=0.01;
this.domEvent.style.filter = "Alpha(opacity=0.01)";
this.domObj.appendChild(this.domEvent);
//changed use an image insetd divs to drow the cross air
var d = document.createElement( 'img' );
d.id="keymapCrossImage";
d.src = this.kaMap.server+"common/images2/cross.png";
d.style.position='absolute';
d.style.top = '0px';
d.style.left = '0px';
d.style.width = "19px";
d.style.height = "19px";
d.style.visibility = 'hidden';
this.domExtents.appendChild(d);
this.domCross = d;
if (this.initialExtents != null) {
this.update( null, this.initialExtents);
}
//create btn to close open the submap
this.btn = document.createElement("img");
this.btn.src = this.kaMap.server + "common/images/minus.gif";
this.btn.onclick = this.closeSubMap;
this.btn.style.position="absolute";
this.btn.style.right="1px";
this.btn.style.top="1px";
this.btn.style.cursor="pointer";
this.btn.parentObj = this;
this.dspFlg=1;
this.domObj.appendChild(this.btn);
this.btn.onclick(); //初期表示しない
};
kaKeymap.prototype.update = function( eventID, extents ) {
if (!this.aExtents || !this.domExtents) {
this.initialExtents = extents;
return;
}
var left = (extents[0] - this.aExtents[0]) / this.cellWidth;
var width = (extents[2] - extents[0]) / this.cellWidth;
var top = -1 * (extents[3] - this.aExtents[3]) / this.cellHeight;
var height = (extents[3] - extents[1]) / this.cellHeight;
this.cx = (extents[0]+extents[2])/2;
this.cy = (extents[1]+extents[3])/2;
this.pxExtent = new Array(left,top,width,height);
this.domExtents.style.top = parseInt(top+0.5)+"px";
this.domExtents.style.left = parseInt(left+0.5)+"px";
this.domEvent.style.top = parseInt(top+0.5)+"px";
this.domEvent.style.left = parseInt(left+0.5)+"px";
if (parseInt(width+0.5) < parseInt(this.domCross.style.width) ||
parseInt(height+0.5) < parseInt(this.domCross.style.height) ) {
//show crosshair and center on center of image
var ix = parseInt(this.domCross.style.width)/2;
var iy = parseInt(this.domCross.style.height)/2;
var ox = width/2;
var oy = height/2;
this.domExtents.style.width = this.domCross.style.width;
this.domExtents.style.height = this.domCross.style.height;
this.domEvent.style.width = this.domCross.style.width;
this.domEvent.style.height = this.domCross.style.height;
this.domExtents.style.top = (parseInt(this.domExtents.style.top) -iy + oy) + 'px';
this.domExtents.style.left = (parseInt(this.domExtents.style.left) -ix + ox) + 'px';
this.domEvent.style.top = (parseInt(this.domEvent.style.top) -iy + oy) + 'px';
this.domEvent.style.left = (parseInt(this.domEvent.style.left) -ix + ox) + 'px';
this.domCross.style.visibility = 'visible';
this.domExtents.style.border = '1px solid white';
this.domEvent.style.border = 'none';
} else {
this.domExtents.style.width = parseInt(width+0.5) + "px";
this.domExtents.style.height = parseInt(height+0.5) + "px";
this.domEvent.style.width = parseInt(width+0.5) + "px";
this.domEvent.style.height = parseInt(height+0.5) + "px";
this.domCross.style.visibility = 'hidden';
this.domExtents.style.border = '1px solid red';
this.domEvent.style.border = '1px solid red';
this.domEvent.style.visibility = 'visible';
this.domExtents.style.visibility = 'visible';
}
var domCx = this.domExtents.offsetLeft + getObjectWidth(this.domExtents)/2;
var domCy = this.domExtents.offsetTop + getObjectHeight(this.domExtents)/2;
// sakai
// リファレンスマップベース地図を更新
//if(top < 0 || left < 0 || (top+height) > this.imgHeight || (left+width) > this.imgWidth){
if(domCx < 0 || domCx > this.imgWidth || domCy < 0 || domCy > this.imgHeight){
this.initialize();
//console.log("renew referencemap");
this.renewcnt++;
}
};
/*click event on div kaKeymap*/
kaKeymap.prototype.onclick = function(e) {
e = (e)?e:((event)?event:null);
this.kaKeymap.centerMap(e);
};
/*call aPixPos to calculate geografic position of click and recenter kamap map*/
kaKeymap.prototype.centerMap = function(e) {
var pos= this.aPixPos( e.clientX, e.clientY );
this.kaMap.zoomTo(pos[0],pos[1]);
};
/**
* kaKeymap_aPixPos( x, y )
*
* try to calculate geoposition in kaKeymap
*
* x - int, the x page coord
* y - int, the y page coord
*
* returns an array with geo positions
*/
kaKeymap.prototype.aPixPos = function( x, y ) {
var obj = this.domObj;
var offsetLeft = 0;
var offsetTop = 0;
while (obj) {
offsetLeft += parseFloat(obj.offsetLeft);
offsetTop += parseFloat(obj.offsetTop);
obj = obj.offsetParent;
}
var pX = x - offsetLeft ;
var pY = y - offsetTop ;
pX = parseFloat(this.aExtents[0] + (this.cellWidth *pX));
pY = parseFloat(this.aExtents[3] - (this.cellHeight *pY));
return [pX,pY];
};
kaKeymap.prototype.mousedown = function(e) {
getRawObject("pointinfo").style.visibility='hidden'; //sakai
e = (e)?e:((event)?event:null);
this.kaKeymap.domEvent.style.top= "0px";
this.kaKeymap.domEvent.style.left= "0px";
this.kaKeymap.domEvent.style.width =this.kaKeymap.domObj.style.width;
this.kaKeymap.domEvent.style.height = this.kaKeymap.domObj.style.height;
this.kaKeymap.domExtents.init=1;
this.kaKeymap.domExtents.oX=e.clientX;
this.kaKeymap.domExtents.oY=e.clientY;
var amount= 50;
this.kaKeymap.domExtents.style.backgroundColor = 'pink';
this.kaKeymap.domExtents.style.opacity=amount/100;
// this.kaKeymap.domObj.style.mozOpacity = amount/100;
//Nasty IE effect (or bug?) when you apply a filter
//to a layer, it clips the layer and we rely on the
//contents being visible outside the layer bounds
//for 'railroading' the tiles
if (this.kaKeymap.kaMap.isIE4) {
this.kaKeymap.domExtents.style.filter = "Alpha(opacity="+amount+")";
}
e=null;
};
kaKeymap.prototype.mouseup = function(e) {
if(this.kaKeymap.domExtents.init) {
e = (e)?e:((event)?event:null);
this.kaKeymap.domExtents.style.backgroundColor = 'transparent';
this.kaKeymap.domExtents.style.opacity=1;
if (this.kaKeymap.kaMap.isIE4) {
this.kaKeymap.domExtents.style.filter = "Alpha(opacity=100)";
}
this.kaKeymap.domExtents.init=0;
var cG=this.kaKeymap.geoCentCoord();
this.kaKeymap.kaMap.zoomTo(cG[0],cG[1]);
}
};
kaKeymap.prototype.mousemove = function(e) {
e = (e)?e:((event)?event:null);
if(this.kaKeymap.domExtents.init) {
var xMov=(this.kaKeymap.domExtents.oX-e.clientX);
var yMov=(this.kaKeymap.domExtents.oY-e.clientY);
var oX=this.kaKeymap.pxExtent[0];
var oY=this.kaKeymap.pxExtent[1];
var nX = oX-xMov;
var nY = oY-yMov;
this.kaKeymap.domExtents.oX= e.clientX;
this.kaKeymap.domExtents.oY= e.clientY;
this.kaKeymap.pxExtent[0] = nX;
this.kaKeymap.pxExtent[1] = nY;
if(this.kaKeymap.domCross.style.visibility == 'visible') {
var ix = parseInt(this.kaKeymap.domCross.style.width)/2;
var iy = parseInt(this.kaKeymap.domCross.style.height)/2;
var ox = this.kaKeymap.pxExtent[2]/2;
var oy = this.kaKeymap.pxExtent[3]/2;
this.kaKeymap.domExtents.style.top = parseInt((nY+0.5)-iy+oy) + "px";
this.kaKeymap.domExtents.style.left = parseInt((nX+0.5)-ix+ox) + "px";
} else {
this.kaKeymap.domExtents.style.top = parseInt(nY+0.5) + "px";
this.kaKeymap.domExtents.style.left = parseInt(nX+0.5) + "px";
}
}
};
/**
* calculate the geographic position of div's center
* Use pxExtent left top width height because the
* div's top left width and heigth (casted to int)
* this avoid in calculation error due to ins casting
**/
kaKeymap.prototype.geoCentCoord = function() {
var cpX = this.pxExtent[0] + this.pxExtent[2]/2;
var cpY = this.pxExtent[1] + this.pxExtent[3]/2;
var cX = this.aExtents[0] + (this.cellWidth *cpX);
var cY = this.aExtents[3] - (this.cellHeight *cpY);
return [cX,cY];
};
kaKeymap.prototype.closeSubMap = function(){
if(this.parentObj.dspFlg == 1){
this.parentObj.domImg.style.display="none";
this.parentObj.domExtents.style.display="none";
this.parentObj.domEvent.style.display="none";
this.parentObj.domObj.style.width="12px";
this.parentObj.domObj.style.height="12px";
this.parentObj.dspFlg = 0;
this.src = this.parentObj.kaMap.server + "common/images/plus.gif";
}else{
this.parentObj.domImg.style.display="block";
this.parentObj.domExtents.style.display="block";
this.parentObj.domEvent.style.display="block";
this.parentObj.domObj.style.width=this.parentObj.width;
this.parentObj.domObj.style.height=this.parentObj.height;
this.parentObj.dspFlg = 1;
this.src = this.parentObj.kaMap.server + "common/images/minus.gif";
}
};var charset="";
/**********************************************************************
*
* $Id: kaTool.js,v 1.34 2006/10/19 02:36:28 pspencer Exp $
*
* purpose: an API for kaMap tools with a default navigation tool provided
*
* author: Paul Spencer (pspencer@dmsolutions.ca)
*
* The original kaTool code was written by DM Solutions Group.
*
* TODO:
*
**********************************************************************
*
* Copyright (c) 2005, DM Solutions Group Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
**********************************************************************/
/*
* includes code inspired by code in WindowManager.js
* Copyright 2005 MetaCarta, Inc., released under the BSD License
*/
//globally
var kaCurrentTool = null;
/**
* @class
* kaTool API.
* An API for building tools that work with kaMap.
* To create a new tool, you need to have included this file first. Next
* create a function to instantiate your new tool. All object construction
* functions must include a parameter that references the kaMap object on which
* they operate.
* The object construction function must call the kaTool constructor using the
* following syntax:
* kaTool.apply( this, [oKaMap] );
* where oKaMap is the name of the parameter to the constructor function.
* You should then set the tool's name (this.name) and overload any functions
* for mouse handling etc.
*
* @constructor kaTool
* kaTool is the base class for tools which operate on an instance of kaMap.
* @param {Object} oKaMap the instance of kaMap on which this tool should operate
*/
function kaTool( oKaMap ) {
/** the instance of kaMap on which this tool operates */
this.kaMap = oKaMap;
/** the name of this tool */
this.name = 'kaTool';
/** info tools get all events all the time */
this.bInfoTool = false;
// Default for mouse wheel: zoom in or out. (Mod D Badke)
this.wheelPlus = new Array(oKaMap, oKaMap.zoomOut, null);
this.wheelMinus = new Array(oKaMap, oKaMap.zoomIn, null);
this.kaMap.registerTool( this );
};
/**
* is this an info tool or a regular tool?
*/
kaTool.prototype.isInfoTool = function() {
return this.bInfoTool;
};
/**
* activate this tool. Activating the tool causes any existing tools to be
* deactivated.
*/
kaTool.prototype.activate = function() {
this.kaMap.activateTool( this );
document.kaCurrentTool = this;
};
/**
* deactivate this tool.
*/
kaTool.prototype.deactivate = function() {
this.kaMap.deactivateTool( this );
document.kaCurrentTool = null;
};
/**
* handle mouse movement over the viewport of the kaMap. This
* method does nothing and should be overloaded by subclasses.
* @param {Event} e the mouse event object
*/
kaTool.prototype.onmousemove = function(e) {
return false;
};
/**
* handle mouse down events on the viewport of the kaMap. This
* method does nothing and should be overloaded by subclasses.
* @param {Event} e the mouse event object
*/
kaTool.prototype.onmousedown = function(e) {
return false;
};
/**
* handle mouse up events on the viewport of the kaMap. This
* method does nothing and should be overloaded by subclasses.
* @param {Event} e the mouse event object
*/
kaTool.prototype.onmouseup = function(e) {
return false;
};
/**
* handle mouse doubleclicks on the viewport of the kaMap. This
* method does nothing and should be overloaded by subclasses.
* @param {Event} e the mouse event object
*/
kaTool.prototype.ondblclick = function(e) {
return false;
};
/**
* Set the object and function to call when the mouse wheel
* event triggers. The parameters are saved in the tool object
* this is called for, and only affect that tool.
*
* @param {array} plusSet - parameters for positive wheel scroll
* @param {array} minusSet - parameters for negative wheel scroll
*
* plusSet and minusSet are arrays of structure:
* [0] - object to apply function for or null
* [1] - function to apply
* [2] - function arguments or null for no arguments
*
* Set minusSet and/or plusSet to null to disable that scroll direction.
*
* eg: --disable mouse wheel for navigator tool:
* myKaNavigator.setMouseWheel(null, null);
*
* --set navigator tool to zoom (same as default action):
* myKaNavigator.setMouseWheel([myKaMap, myKaMap.zoomIn, null],
* [myKaMap, myKaMap.zoomOut, null]);
*
* (New D Badke)
*/
kaTool.prototype.setMouseWheel = function(minusSet, plusSet) {
this.wheelMinus = minusSet;
this.wheelPlus = plusSet;
};
/**
* Handle mouse wheel events over the viewport of the kaMap. This
* applies a function set by the setMouseWheel function. If the function
* is null, do nothing. (Mod D Badke)
*
* @param {Event} e the mouse event object
*/
kaTool.prototype.onmousewheel = function(e) {
e = (e)?e:((event)?event:null);
var wheelDelta = e.wheelDelta ? e.wheelDelta : e.detail*-1;
var wheelSet = null;
if (wheelDelta > 0)
wheelSet = this.wheelMinus;
else
wheelSet = this.wheelPlus;
if (wheelSet) {
obj = (wheelSet[0]) ? wheelSet[0] : null;
func = (wheelSet[1]) ? wheelSet[1] : null;
args = (wheelSet[2]) ? wheelSet[2] : null;
if (func) {
if (args) {
func.apply(obj, args);
} else{
func.apply(obj);
}
}
}
};
/**
* adjust a page-relative pixel position into a kaMap relative
* pixel position
*
* @param {Integer} x the x page coordinate to convert
* @param {Integer} y the y page coordinate to convert
* @return {Array} return an array containing the converted coordinates
*/
kaTool.prototype.adjustPixPosition = function( x, y ) {
var obj = this.kaMap.domObj;
var offsetLeft = 0;
var offsetTop = 0;
while (obj) {
offsetLeft += parseInt(obj.offsetLeft);
offsetTop += parseInt(obj.offsetTop);
obj = obj.offsetParent;
}
var pX = parseInt(this.kaMap.theInsideLayer.style.left) +
offsetLeft - this.kaMap.xOrigin - x;
var pY = parseInt(this.kaMap.theInsideLayer.style.top) +
offsetTop - this.kaMap.yOrigin - y;
return [pX,pY];
};
/*
* key press events are directed to the HTMLDocument rather than the
* div on which we really wanted them to happen. So we set the document
* keypress handler to this function and redirect it to the kaMap core
* keypress handler, which will eventually reach the onkeypress handler
* of our current tool ... which by default is the keyboard navigation.
*
* To get the keyboard events in the first place, add the following when you
* want the keypress events to be captured
*
* if (isIE4) document.onkeydown = kaTool_redirect_onkeypress;
* document.onkeypress = kaTool_redirect_onkeypress;
*/
function kaTool_redirect_onkeypress(e) {
if (document.kaCurrentTool) {
document.kaCurrentTool.onkeypress(e);
}
};
/**
* handle keypress events. Keypress events are normally dispatched
* here rather than in a sub-class.
* @param {Event} e the keypress event object
*/
kaTool.prototype.onkeypress = function(e) {
e = (e)?e:((event)?event:null);
if (e) {
var charCode=(e.charCode)?e.charCode:e.keyCode;
var b=true;
var nStep = 16;
switch(charCode) {
case 38://up
this.kaMap.moveBy(0,nStep);
this.kaMap.triggerEvent( KAMAP_EXTENTS_CHANGED, this.kaMap.getGeoExtents() );
break;
case 40:
this.kaMap.moveBy(0,-nStep);
this.kaMap.triggerEvent( KAMAP_EXTENTS_CHANGED, this.kaMap.getGeoExtents() );
break;
case 37:
this.kaMap.moveBy(nStep,0);
this.kaMap.triggerEvent( KAMAP_EXTENTS_CHANGED, this.kaMap.getGeoExtents() );
break;
case 39:
this.kaMap.moveBy(-nStep,0);
this.kaMap.triggerEvent( KAMAP_EXTENTS_CHANGED, this.kaMap.getGeoExtents() );
break;
case 33:
this.kaMap.slideBy(0, this.kaMap.viewportHeight/2);
break;
case 34:
this.kaMap.slideBy(0,-this.kaMap.viewportHeight/2);
break;
case 36:
this.kaMap.slideBy(this.kaMap.viewportWidth/2,0);
break;
case 35:
this.kaMap.slideBy(-this.kaMap.viewportWidth/2,0);
break;
case 43: //ascii +
case 61: //ascii =
this.kaMap.zoomIn();
break;
case 45:
this.kaMap.zoomOut();
break;
default:
b=false;
}
if (b) {
return this.cancelEvent(e);
}
return true;
}
};
/**
* handle the mouse moving over the kaMap viewport. This is a method does
* nothing and should be overloaded in a subclass
* @param {Event} e the mouse event
*/
kaTool.prototype.onmouseover = function(e) {
return false;
};
/**
* handle the mouse leaving the kaMap viewport. This is a method
* releases the keypress handler and should be called from any
* sub class that overloads this method.
* @param {Event} e the mouse event
*/
kaTool.prototype.onmouseout = function(e) {
if (this.kaMap.isIE4) {
document.onkeydown = null;
}
document.onkeypress = null;
return false;
};
/**
* provide a cross-platform method of cancelling events, including
* stopping of event bubbling and propagation.
* @param {Event} e the event to cancel
*/
kaTool.prototype.cancelEvent = function(e) {
e = (e)?e:((event)?event:null);
e.cancelBubble = true;
e.returnValue = false;
if (e.stopPropogation) {
e.stopPropogation();
}
if (e.preventDefault) {
e.preventDefault();
}
return false;
};
/**
* Construct a new kaNavigator instance on a given kaMap instance
*
* @class
* kaNavigator is a general purpose navigation tool for kaMap instances.
* It provides panning through click-and-drag, and various keyboard
* navigation.
*
* @base kaTool
* @constructor
* @param {Object} oKaMap the kaMap instance to provide navigation for
* @author Paul Spencer
*/
function kaNavigator( oKaMap ) {
kaTool.apply( this, [oKaMap] );
/** the name of this tool */
this.name = 'kaNavigator';
/** the cursor to use when the map is not being dragged */
//this.cursorNormal = ["url('images/grab.cur'),move", '-moz-grab', 'grab', 'move'];
this.cursorNormal = ['-moz-grab', 'grab', 'move'];
/** the cursor to use when the map is being dragged */
//this.cursorDrag = ["url('images/grabbing.cur'),move", '-moz-grabbing', 'grabbing', 'move'];
this.cursorDrag = ['-moz-grabbing', 'grabbing', 'move'];
/** the cursor to use over the map (by default) */
this.cursor = this.cursorNormal;
/** the image to use for this tool when it is active on the map */
this.activeImage = this.kaMap.server + 'images/button_pan_3.png';
/** the image to use for this tool when it is disabled */
this.disabledImage = this.kaMap.server + 'images/button_pan_2.png';
/** track the last x position of the mouse for panning */
this.lastx = null;
/** track the last y position of the mouse for panning */
this.lasty = null;
/** track whether the mouse is down or up for panning support */
this.bMouseDown = false;
for (var p in kaTool.prototype) {
if (!kaNavigator.prototype[p])
kaNavigator.prototype[p]= kaTool.prototype[p];
}
};
/**
* handle the mouse leaving the viewport. If the mouse is down, stop
* dragging.
* @param {Event} e the mouse event object
*/
kaNavigator.prototype.onmouseout = function(e) {
e = (e)?e:((event)?event:null);
if (!e.target) e.target = e.srcElement;
if (e.target.id == this.kaMap.domObj.id) {
this.bMouseDown = false;
return kaTool.prototype.onmouseout.apply(this, [e]);
}
};
/**
* handle the mouse moving inside viewport. If the mouse is down, move
* the map.
* @param {Event} e the mouse event object
*/
kaNavigator.prototype.onmousemove = function(e) {
e = (e)?e:((event)?event:null);
if (!this.bMouseDown) {
return false;
}
if (!this.kaMap.layersHidden) {
this.kaMap.hideLayers();
}
var newTop = safeParseInt(this.kaMap.theInsideLayer.style.top);
var newLeft = safeParseInt(this.kaMap.theInsideLayer.style.left);
var x = e.pageX || (e.clientX +
(document.documentElement.scrollLeft || document.body.scrollLeft));
var y = e.pageY || (e.clientY +
(document.documentElement.scrollTop || document.body.scrollTop));
newTop = newTop - this.lasty + y;
newLeft = newLeft - this.lastx + x;
this.kaMap.theInsideLayer.style.top=newTop + 'px';
this.kaMap.theInsideLayer.style.left=newLeft + 'px';
this.kaMap.checkWrap.apply(this.kaMap, []);
this.lastx=x;
this.lasty=y;
return false;
};
/**
* handle mouse down events. Start tracking mouse movement for panning.
* @param {Event} e the mouse event object
*/
kaNavigator.prototype.onmousedown = function(e) {
e = (e)?e:((event)?event:null);
if (e.button==2) {
return this.cancelEvent(e);
} else {
this.cursor = this.cursorDrag;
this.kaMap.setCursor(this.cursorDrag);
if (this.kaMap.isIE4) {
document.onkeydown = kaTool_redirect_onkeypress;
}
document.onkeypress = kaTool_redirect_onkeypress;
this.bMouseDown=true;
var x = e.pageX || (e.clientX +
(document.documentElement.scrollLeft || document.body.scrollLeft));
var y = e.pageY || (e.clientY +
(document.documentElement.scrollTop || document.body.scrollTop));
this.lastx=x;
this.lasty=y;
this.startx = this.lastx;
this.starty = this.lasty;
e.cancelBubble = true;
e.returnValue = false;
if (e.stopPropogation) e.stopPropogation();
if (e.preventDefault) e.preventDefault();
return false;
}
};
var gDblClickTimer = null;
/**
* handle the mouse up events. Stop tracking mouse movement.
* @param {Event} e the mouse event object
*/
kaNavigator.prototype.onmouseup = function(e) {
this.cursor = this.cursorNormal;
this.kaMap.setCursor(this.cursorNormal);
e = (e)?e:((event)?event:null);
this.bMouseDown=false;
var x = e.pageX || (e.clientX +
(document.documentElement.scrollLeft || document.body.scrollLeft));
var y = e.pageY || (e.clientY +
(document.documentElement.scrollTop || document.body.scrollTop));
if (Math.abs(x-this.startx) < 2 &&
Math.abs(y-this.starty) < 2) {
if (!gDblClickTimer) {
gDblClickTimer = window.setTimeout(bind(this.dispatchMapClicked, this, x, y), 250);
}
} else {
gDblClickTimer = null;
this.kaMap.showLayers();
this.kaMap.triggerEvent(KAMAP_EXTENTS_CHANGED, this.kaMap.getGeoExtents());
}
return false;
};
kaNavigator.prototype.dispatchMapClicked = function(px,py) {
var a = this.adjustPixPosition( px,py );
var p = this.kaMap.pixToGeo( a[0],a[1] );
gDblClickTimer=null;
this.kaMap.triggerEvent(KAMAP_MAP_CLICKED, p);
};
/**
* handle a double-click event by sliding the map to the point that was clicked.
* @param {Event} e the mouse event object
*/
kaNavigator.prototype.ondblclick = function(e) {
if (gDblClickTimer) {
window.clearTimeout(gDblClickTimer);
gDblClickTimer = null;
}
e = (e)?e:((event)?event:null);
var x = e.pageX || (e.clientX +
(document.documentElement.scrollLeft || document.body.scrollLeft));
var y = e.pageY || (e.clientY +
(document.documentElement.scrollTop || document.body.scrollTop));
var a = this.adjustPixPosition( x,y );
var p = this.kaMap.pixToGeo( a[0], a[1] );
this.kaMap.zoomTo(p[0],p[1]);
};
//TODO: this is a temporary patch until we add prototype/scriptaculous support.
function bind(m,o) {
var __method = arguments[0];
var __object = arguments[1];
var args = [];
for (var i=2; i
*
* 2) create a new instance of kaQuery
*
* myKaQuery = new kaQuery( myKaMap, KAMAP_RECT_QUERY );
*
* or if you want to do something when mouse stops over the viewport (delay is 400ms here) :
*
* myKaQuery = new kaQuery( myKaMap, KAMAP_MOUSE_STOPPED, 400 );
* myKaQuery.activate();
*
* 3) provide some way of activating it ( not necessary with KAMAP_MOUSE_STOPPED, it's always activated)
* This example would allow switching between querying and navigating.
*
*
*
*
* 4) listen for the query event
*
* myKaMap.registerForEvent( KAMAP_QUERY, null, myQuery );
* myKaMap.resgisterForEvent( KAMAP_MOUSE_STOPPED, null, myMouseStopped );
*
* 5) and do something when the user requests a query
*
* function myQuery( eventID, queryType, coords )
* {
* alert( "QUERY: " + queryType + " " + coords );
* }
*
*
* Querying actually does nothing except generate a KAMAP_QUERY event with
* the query type and coordinates passed as parameters to the event handler
*
* Signature of the query event handler is:
*
* function myQueryHandler( eventID, queryType, queryCoords )
*
* eventID: int, KAMAP_QUERY
*
* queryType: int, one of KAMAP_POINT_QUERY, KAMAP_RECT_QUERY or KAMAP_MOUSE_STOPPED
*
* queryCoords: array, array of two or four floating point coordinates
* depending on the query type
*
* You can affect the style of the zoom box by changing oQuery.domObj.style as
* you would with any other HTML element (it's a div).
*
*****************************************************************************/
// the query event id
var KAMAP_QUERY = gnLastEventId ++;
// human names for the query types
var KAMAP_POINT_QUERY = 0;
var KAMAP_RECT_QUERY = 1;
// ********************** ADDED BY SEBASTIEN ROCH ***************************
var KAMAP_MOUSE_STOPPED = 2;
// ************************** END MODIF ************************
/*
* Main function
* constructor : (oKaMap, type, [delay])
* If type is KAMAP_MOUSE_STOPPED, you have to set up the delay after
* which this event is triggered, or default is 500ms
*/
function kaQuery( oKaMap, type ) {
kaTool.apply( this, [oKaMap] );
this.type = type;
// ********************** ADDED BY SEBASTIEN ROCH ***************************
if(this.type == KAMAP_MOUSE_STOPPED){
this.bInfoTool = true;
// check arguments
if(arguments.length == 3){
this.delay = arguments[2];
} else {
alert("Incorrect nb of arguments for instance kaQuery. Delay will be set by default to 500ms");
this.delay = 500;
}
}
// ************************** END MODIF ************************
this.name = 'kaQuery';
this.cursor = 'help';
this.startx = null;
this.starty = null;
this.endx = null;
this.endy = null;
this.bMouseDown = false;
// ********************** ADDED BY SEBASTIEN ROCH ***************************
// array for storing geo coords when mouse is stopped
this.coords = new Array();
// flag
this.mouseStopped = false;
this.chrono = null;
// ************************** END MODIF ************************
//this is the HTML element that is visible
this.domObj = document.createElement( 'div' );
this.domObj.style.position = 'absolute';
this.domObj.style.top = '0px';
this.domObj.style.left = '0px';
this.domObj.style.width = '1px';
this.domObj.style.height = '1px';
this.domObj.style.zIndex = 50;
this.domObj.style.visibility = 'hidden';
this.domObj.style.border = '1px solid red';
this.domObj.style.backgroundColor = 'white';
this.domObj.style.opacity = 0.50;
this.domObj.style.mozOpacity = 0.50;
this.domObj.style.filter = 'Alpha(opacity=50)';
this.kaMap.theInsideLayer.appendChild( this.domObj );
for (var p in kaTool.prototype) {
if (!kaQuery.prototype[p])
kaQuery.prototype[p]= kaTool.prototype[p];
}
};
/*
* draw a box representing the query region.
*
* kaQuery maintains the query region in four variables. The variables are
* assumed to be in pixel coordinates and are used to position the box. If
* any of the coordinates are null, clear the query box.
*/
kaQuery.prototype.drawZoomBox = function() {
if (this.startx == null || this.starty == null ||
this.endx == null || this.endy == null ) {
this.domObj.style.visibility = 'hidden';
this.domObj.style.top = '0px';
this.domObj.style.left = '0px';
this.domObj.style.width = '1px';
this.domObj.style.height = '1px';
return;
}
this.domObj.style.visibility = 'visible';
if (this.endx < this.startx) {
this.domObj.style.left = (this.endx - this.kaMap.xOrigin) + 'px';
this.domObj.style.width = (this.startx - this.endx) + "px";
}
else {
this.domObj.style.left = (this.startx - this.kaMap.xOrigin) + 'px';
this.domObj.style.width = (this.endx - this.startx) + "px";
}
if (this.endy < this.starty) {
this.domObj.style.top = (this.endy - this.kaMap.yOrigin) + 'px';
this.domObj.style.height = (this.starty - this.endy) + "px";
} else {
this.domObj.style.top = (this.starty - this.kaMap.yOrigin) + 'px';
this.domObj.style.height = (this.endy - this.starty) + "px";
}
};
/**
* kaQuery.onmousemove( e )
*
* called when the mouse moves over theInsideLayer.
*
* e - object, the event object or null (in ie)
*/
kaQuery.prototype.onmousemove = function(e) {
e = (e)?e:((event)?event:null);
// ********************** ADDED BY SEBASTIEN ROCH ***************************
// don't return false if we are handling a KAMAP_MOUSE_STOPPED query
if(this.type != KAMAP_MOUSE_STOPPED){
if (!this.bMouseDown) {
return false;
}
}
// ************************** END MODIF ************************
var x = e.pageX || (e.clientX +
(document.documentElement.scrollLeft || document.body.scrollLeft));
var y = e.pageY || (e.clientY +
(document.documentElement.scrollTop || document.body.scrollTop));
// ********************** MODIFIED/ADDED BY SEBASTIEN ROCH ***************************
var adjCoords = this.adjustPixPosition( x, y );
if(this.type == KAMAP_MOUSE_STOPPED){
// get geo position
var p = this.kaMap.pixToGeo(adjCoords[0], adjCoords[1]);
this.coords[0] = p[0];
this.coords[1] = p[1];
// if chrono is ON, we reset it
if(this.chrono != null)
clearTimeout(this.chrono);
// call the onmousestop function after a delay if mouse doesn't move anymore
var t = this;
if(this.mouseStopped == false){
this.chrono = setTimeout(function(){t.onmousestop()}, this.delay);
}
}
if (this.type == KAMAP_RECT_QUERY) {
this.endx = -adjCoords[0];
this.endy = -adjCoords[1];
this.drawZoomBox();
}
// ************************** END MODIF ************************
return false;
};
// ********************** MODIFIED/ADDED BY SEBASTIEN ROCH ***************************
/**
* kaQuery.onmousestop()
*
* called if mouse is stopped during "this.delay"
*
*/
kaQuery.prototype.onmousestop = function(){
// stop chrono
clearTimeout(this.chrono);
// update flag -> avoid calling the onmousestop function if it's already being called
this.mouseStopped = true;
this.kaMap.triggerEvent(KAMAP_MOUSE_STOPPED, this.type, this.coords);
this.mouseStopped = false;
return;
};
// ************************** END MODIF ************************
/**
* kaQuery.onmouseout( e )
*
* called when the mouse leaves theInsideLayer. Terminate the query
*
* e - object, the event object or null (in ie)
*/
kaQuery.prototype.onmouseout = function(e) {
e = (e)?e:((event)?event:null);
// ********** MODIFIED/ADDED BY SEBASTIEN ROCH ******************
clearTimeout(this.chrono);
// ************************** END MODIF ************************
if (!e.target) e.target = e.srcElement;
if (e.target.id == this.kaMap.domObj.id) {
this.bMouseDown = false;
this.startx = this.endx = this.starty = this.endy = null;
this.drawZoomBox();
return kaTool.prototype.onmouseout.apply(this, [e]);
}
};
/**
* kaQuery.onmousedown( e )
*
* called when a mouse button is pressed over theInsideLayer.
*
* e - object, the event object or null (in ie)
*/
kaQuery.prototype.onmousedown = function(e) {
e = (e)?e:((event)?event:null);
// ********** MODIFIED/ADDED BY SEBASTIEN ROCH ******************
// we "desactivate" clicks if type is KAMAP_MOUSE_STOPPED
if(this.type != KAMAP_MOUSE_STOPPED){
// ************************** END MODIF ************************
if (e.button==2) {
return this.cancelEvent(e);
}
else {
if (this.kaMap.isIE4)
document.onkeydown = kaTool_redirect_onkeypress;
document.onkeypress = kaTool_redirect_onkeypress;
this.bMouseDown = true;
var x = e.pageX || (e.clientX +
(document.documentElement.scrollLeft || document.body.scrollLeft));
var y = e.pageY || (e.clientY +
(document.documentElement.scrollTop || document.body.scrollTop));
var aPixPos = this.adjustPixPosition( x,y );
this.startx=this.endx = -aPixPos[0];
this.starty=this.endy = -aPixPos[1];
this.drawZoomBox();
e.cancelBubble = true;
e.returnValue = false;
if (e.stopPropagation) e.stopPropagation();
if (e.preventDefault) e.preventDefault();
return false;
}
}
};
/**
* kaQuery.onmouseup( e )
*
* called when a mouse button is clicked over theInsideLayer.
*
* e - object, the event object or null (in ie)
*/
kaQuery.prototype.onmouseup = function(e) {
e = (e)?e:((event)?event:null);
// ********** MODIFIED/ADDED BY SEBASTIEN ROCH ******************
// we "desactivate" clicks if type is KAMAP_MOUSE_STOPPED
if(this.type != KAMAP_MOUSE_STOPPED){
// ************************** END MODIF ************************
var type = KAMAP_POINT_QUERY;
var start = this.kaMap.pixToGeo( -this.startx, -this.starty );
var coords = start;
if (this.startx!=this.endx&&this.starty!=this.endy) {
type = KAMAP_RECT_QUERY;
coords = start.concat(this.kaMap.pixToGeo( -this.endx, -this.endy ));
if(coords[2] < coords[0]) {
//minx gt maxx than I invert values
var minx = coords[2];
var maxx = coords[0];
coords[0] = minx;
coords[2] = maxx;
}
if(coords[1] < coords[3]){
//miny gt maggiore than I invert values
var miny = coords[1];
var maxy = coords[3];
coords[3] = miny;
coords[1] = maxy;
}
}
this.kaMap.triggerEvent(KAMAP_QUERY, type, coords);
this.startx = this.endx = this.starty = this.endy = null;
this.drawZoomBox();
}
return false;
};var charset="";
/*
JavaScript Scalebar for MapServer (scalebar.js)
Copyright (c) 2005 Tim Schaub of CommEn Space (http://www.commenspace.org)
This is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 2.1 of the License, or (at
your option) any later version.
This software is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this software; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
v1.3.1 - removed a typo that affected .sbBar with borders (thanks jlivni)
- scalebar is now centered on .sbWrapper div by default, more css control
- reduced likelihood of displaying very large numbers
- added condition to deal with @import styles (thanks dokai)
*/
function ScaleBar(scaleDenominator) {
// default properties
// may be modified after construction
// if modified after ScaleBar.place(), use ScaleBar.update()
this.scaleDenominator = (scaleDenominator == null) ? 1 : scaleDenominator;
this.displaySystem = 'metric'; // metric or english supported
this.minWidth = 100; // pixels
this.maxWidth = 200; // pixels
this.divisions = 2;
this.subdivisions = 2;
this.showMinorMeasures = false;
this.abbreviateLabel = false;
this.singleLine = false;
this.resolution = 72; // dpi
this.align = 'center'; // left, center, or right supported
// create scalebar elements
this.container = document.createElement('div');
this.container.className = 'sbWrapper';
this.labelContainer = document.createElement('div');
this.labelContainer.className = 'sbUnitsContainer';
this.labelContainer.style.position = 'absolute';
this.graphicsContainer = document.createElement('div');
this.graphicsContainer.style.position = 'absolute';
this.graphicsContainer.className = 'sbGraphicsContainer';
this.numbersContainer = document.createElement('div');
this.numbersContainer.style.position = 'absolute';
this.numbersContainer.className = 'sbNumbersContainer';
// private functions
// put in some markers and bar pieces so style attributes can be grabbed
// this is a solution for Safari support
var markerMajor = document.createElement('div');
markerMajor.className = 'sbMarkerMajor';
this.graphicsContainer.appendChild(markerMajor);
var markerMinor = document.createElement('div');
markerMinor.className = 'sbMarkerMinor';
this.graphicsContainer.appendChild(markerMinor);
var barPiece = document.createElement('div');
barPiece.className = 'sbBar';
this.graphicsContainer.appendChild(barPiece);
var barPieceAlt = document.createElement('div');
barPieceAlt.className = 'sbBarAlt';
this.graphicsContainer.appendChild(barPieceAlt);
}
ScaleBar.prototype.update = function(scaleDenominator) {
if(scaleDenominator != null) {
this.scaleDenominator = scaleDenominator;
};
// local functions (and object constructors)
function HandsomeNumber(smallUglyNumber, bigUglyNumber, sigFigs) {
var sigFigs = (sigFigs == null) ? 10 : sigFigs;
var bestScore = Number.POSITIVE_INFINITY;
var bestTieBreaker = Number.POSITIVE_INFINITY;
// if all else fails, return a small ugly number
var handsomeValue = smallUglyNumber;
var handsomeNumDec = 3;
// try the first three comely multiplicands (in order of comliness)
for(var halvingExp = 0; halvingExp < 3; ++halvingExp) {
var comelyMultiplicand = Math.pow(2, (-1 * halvingExp));
var maxTensExp = Math.floor(Math.log(bigUglyNumber / comelyMultiplicand) / Math.LN10);
for(var tensExp = maxTensExp; tensExp > (maxTensExp - sigFigs + 1); --tensExp) {
var numDec = Math.max(halvingExp - tensExp, 0);
var testMultiplicand = comelyMultiplicand * Math.pow(10, tensExp);
// check if there is an integer multiple of testMultiplicand between smallUglyNumber and bigUglyNumber
if((testMultiplicand * Math.floor(bigUglyNumber / testMultiplicand)) >= smallUglyNumber) {
// check if smallUglyNumber is an integer multiple of testMultiplicand
if(smallUglyNumber % testMultiplicand == 0) {
var testMultiplier = smallUglyNumber / testMultiplicand;
}
// otherwise go for the smallest integer multiple between small and big
else {
var testMultiplier = Math.floor(smallUglyNumber / testMultiplicand) + 1;
}
// test against the best (lower == better)
var testScore = testMultiplier + (2 * halvingExp);
var testTieBreaker = (tensExp < 0) ? (Math.abs(tensExp) + 1) : tensExp;
if((testScore < bestScore) || ((testScore == bestScore) && (testTieBreaker < bestTieBreaker))) {
bestScore = testScore;
bestTieBreaker = testTieBreaker;
handsomeValue = (testMultiplicand * testMultiplier).toFixed(numDec);
handsomeNumDec = numDec;
}
}
}
}
this.value = handsomeValue;
this.score = bestScore;
this.tieBreaker = bestTieBreaker;
this.numDec = handsomeNumDec;
};
HandsomeNumber.prototype.toString = function() {
return this.value.toString();
};
HandsomeNumber.prototype.valueOf = function() {
return this.value;
};
function styleValue(aSelector, styleKey) {
// returns an integer value associated with a particular selector and key
// given a stylesheet with .someSelector {border: 2px solid red}
// styleValue('.someSelector', 'borderWidth') returns 2
var aValue = 0;
if(document.styleSheets) {
for(var sheetIndex = document.styleSheets.length - 1; sheetIndex >= 0; --sheetIndex) {
var aSheet = document.styleSheets[sheetIndex];
if(!aSheet.disabled) {
var allRules;
try{
if(typeof(aSheet.cssRules) == 'undefined') {
if(typeof(aSheet.rules) == 'undefined') {
// can't get rules, assume zero
return 0;
}
else {
allRules = aSheet.rules;
}
}
else {
allRules = aSheet.cssRules;
}
}catch(e){
return 0;
}
if(!(allRules)) allRules = []; //GoogleChromeŃG[ɂȂsC
for(var ruleIndex = 0; ruleIndex < allRules.length; ++ruleIndex) {
var aRule = allRules[ruleIndex];
if(aRule.selectorText && (aRule.selectorText.toLowerCase() == aSelector.toLowerCase())) {
if(aRule.style[styleKey] != '') {
aValue = parseInt(aRule.style[styleKey]);
}
}
}
}
}
}
// if the styleKey was not found, the equivalent value is zero
return aValue ? aValue : 0;
};
function formatNumber(aNumber, numDecimals) {
numDecimals = (numDecimals) ? numDecimals : 0;
var formattedInteger = '' + Math.round(aNumber);
var thousandsPattern = /(-?[0-9]+)([0-9]{3})/;
while(thousandsPattern.test(formattedInteger)) {
formattedInteger = formattedInteger.replace(thousandsPattern, '$1,$2');
}
if(numDecimals > 0) {
var formattedDecimal = Math.floor(Math.pow(10, numDecimals) * (aNumber - Math.round(aNumber)));
if(formattedDecimal == 0) {
return formattedInteger;
}
else {
return formattedInteger + '.' + formattedDecimal;
}
}
else {
return formattedInteger;
}
};
// update the container title (for displaying scale as a tooltip)
this.container.title = 'scale 1:' + formatNumber(this.scaleDenominator);
// measurementProperties holds display units, abbreviations,
// and conversion to inches (since we're using dpi) - per measurement sytem
var measurementProperties = new Object();
measurementProperties.english = {
units: ['miles', 'feet', 'inches'],
abbr: ['mi', 'ft', 'in'],
inches: [63360, 12, 1]
};
measurementProperties.metric = {
units: ['kilometers', 'meters', 'centimeters'],
abbr: ['km', 'm', 'cm'],
inches: [39370.07874, 39.370079, 0.393701]
};
// check each measurement unit in the display system
var comparisonArray = new Array();
for(var unitIndex = 0; unitIndex < measurementProperties[this.displaySystem].units.length; ++unitIndex) {
comparisonArray[unitIndex] = new Object();
var pixelsPerDisplayUnit = this.resolution * measurementProperties[this.displaySystem].inches[unitIndex] / this.scaleDenominator;
var minSDDisplayLength = (this.minWidth / pixelsPerDisplayUnit) / (this.divisions * this.subdivisions);
var maxSDDisplayLength = (this.maxWidth / pixelsPerDisplayUnit) / (this.divisions * this.subdivisions);
// add up scores for each marker (even if numbers aren't displayed)
for(var valueIndex = 0; valueIndex < (this.divisions * this.subdivisions); ++valueIndex) {
var minNumber = minSDDisplayLength * (valueIndex + 1);
var maxNumber = maxSDDisplayLength * (valueIndex + 1);
var niceNumber = new HandsomeNumber(minNumber, maxNumber);
comparisonArray[unitIndex][valueIndex] = {value: (niceNumber.value / (valueIndex + 1)), score: 0, tieBreaker: 0, numDec: 0, displayed: 0};
// now tally up scores for all values given this subdivision length
for(var valueIndex2 = 0; valueIndex2 < (this.divisions * this.subdivisions); ++valueIndex2) {
displayedValuePosition = niceNumber.value * (valueIndex2 + 1) / (valueIndex + 1);
niceNumber2 = new HandsomeNumber(displayedValuePosition, displayedValuePosition);
var isMajorMeasurement = ((valueIndex2 + 1) % this.subdivisions == 0);
var isLastMeasurement = ((valueIndex2 + 1) == (this.divisions * this.subdivisions));
if((this.singleLine && isLastMeasurement) || (!this.singleLine && (isMajorMeasurement || this.showMinorMeasures))) {
// count scores for displayed marker measurements
comparisonArray[unitIndex][valueIndex].score += niceNumber2.score;
comparisonArray[unitIndex][valueIndex].tieBreaker += niceNumber2.tieBreaker;
comparisonArray[unitIndex][valueIndex].numDec = Math.max(comparisonArray[unitIndex][valueIndex].numDec, niceNumber2.numDec);
comparisonArray[unitIndex][valueIndex].displayed += 1;
}
else {
// count scores for non-displayed marker measurements
comparisonArray[unitIndex][valueIndex].score += niceNumber2.score / this.subdivisions;
comparisonArray[unitIndex][valueIndex].tieBreaker += niceNumber2.tieBreaker / this.subdivisions;
}
}
// adjust scores so numbers closer to 1 are preferred for display
var scoreAdjustment = (unitIndex + 1) * comparisonArray[unitIndex][valueIndex].tieBreaker / comparisonArray[unitIndex][valueIndex].displayed;
comparisonArray[unitIndex][valueIndex].score *= scoreAdjustment;
}
}
// get the value (subdivision length) with the lowest cumulative score
var subdivisionDisplayLength = null;
var displayUnits = null;
var displayUnitsAbbr = null;
var subdivisionPixelLength = null;
var bestScore = Number.POSITIVE_INFINITY;
var bestTieBreaker = Number.POSITIVE_INFINITY;
var numDec = 0;
for(var unitIndex = 0; unitIndex < comparisonArray.length; ++unitIndex) {
for(valueIndex in comparisonArray[unitIndex]) {
if((comparisonArray[unitIndex][valueIndex].score < bestScore) || ((comparisonArray[unitIndex][valueIndex].score == bestScore) && (comparisonArray[unitIndex][valueIndex].tieBreaker < bestTieBreaker))) {
bestScore = comparisonArray[unitIndex][valueIndex].score;
bestTieBreaker = comparisonArray[unitIndex][valueIndex].tieBreaker;
subdivisionDisplayLength = comparisonArray[unitIndex][valueIndex].value;
numDec = comparisonArray[unitIndex][valueIndex].numDec;
displayUnits = measurementProperties[this.displaySystem].units[unitIndex];
displayUnitsAbbr = measurementProperties[this.displaySystem].abbr[unitIndex];
pixelsPerDisplayUnit = this.resolution * measurementProperties[this.displaySystem].inches[unitIndex] / this.scaleDenominator;
subdivisionPixelLength = pixelsPerDisplayUnit * subdivisionDisplayLength; // round before use in style
}
}
}
// determine offsets for graphic elements
var xOffsetMarkerMajor = (styleValue('.sbMarkerMajor', 'borderLeftWidth') + styleValue('.sbMarkerMajor', 'width') + styleValue('.sbMarkerMajor', 'borderRightWidth')) / 2;
var xOffsetMarkerMinor = (styleValue('.sbMarkerMinor', 'borderLeftWidth') + styleValue('.sbMarkerMinor', 'width') + styleValue('.sbMarkerMinor', 'borderRightWidth')) / 2;
var xOffsetBar = (styleValue('.sbBar', 'borderLeftWidth') + styleValue('.sbBar', 'borderRightWidth')) / 2;
var xOffsetBarAlt = (styleValue('.sbBarAlt', 'borderLeftWidth') + styleValue('.sbBarAlt', 'borderRightWidth')) / 2;
// support for browsers without the Document.styleSheets property (Opera)
if(!document.styleSheets) {
// this is a two part hack, one for the offsets here and one for the css below
xOffsetMarkerMajor = 0.5;
xOffsetMarkerMinor = 0.5;
}
// clean out any old content from containers
while(this.labelContainer.hasChildNodes()) {
this.labelContainer.removeChild(this.labelContainer.firstChild);
}
while(this.graphicsContainer.hasChildNodes()) {
this.graphicsContainer.removeChild(this.graphicsContainer.firstChild);
}
while(this.numbersContainer.hasChildNodes()) {
this.numbersContainer.removeChild(this.numbersContainer.firstChild);
}
// create all divisions
var aMarker, aBarPiece, numbersBox, xOffset;
var alignmentOffset = {
left: 0,
center: (-1 * this.divisions * this.subdivisions * subdivisionPixelLength / 2),
right: (-1 * this.divisions * this.subdivisions * subdivisionPixelLength)
};
var xPosition = 0 + alignmentOffset[this.align];
var markerMeasure = 0;
for(var divisionIndex = 0; divisionIndex < this.divisions; ++divisionIndex) {
// set xPosition and markerMeasure to start of division
xPosition = divisionIndex * this.subdivisions * subdivisionPixelLength;
xPosition += alignmentOffset[this.align];
markerMeasure = (divisionIndex == 0) ? 0 : ((divisionIndex * this.subdivisions) * subdivisionDisplayLength).toFixed(numDec);
// add major marker
aMarker = document.createElement('div');
aMarker.className = 'sbMarkerMajor';
aMarker.style.position = 'absolute';
aMarker.style.overflow = 'hidden';
aMarker.style.left = Math.round(xPosition - xOffsetMarkerMajor) + 'px';
aMarker.appendChild(document.createTextNode(' '));
this.graphicsContainer.appendChild(aMarker);
// add initial measure
if(!this.singleLine) {
numbersBox = document.createElement('div');
numbersBox.className = 'sbNumbersBox';
numbersBox.style.position = 'absolute';
numbersBox.style.overflow = 'hidden';
numbersBox.style.textAlign = 'center';
if(this.showMinorMeasures) {
numbersBox.style.width = Math.round(subdivisionPixelLength * 2) + 'px';
numbersBox.style.left = Math.round(xPosition - subdivisionPixelLength) + 'px';
}
else {
numbersBox.style.width = Math.round(this.subdivisions * subdivisionPixelLength * 2) + 'px';
numbersBox.style.left = Math.round(xPosition - (this.subdivisions * subdivisionPixelLength)) + 'px';
}
numbersBox.appendChild(document.createTextNode(markerMeasure));
this.numbersContainer.appendChild(numbersBox);
}
// create all subdivisions
for(var subdivisionIndex = 0; subdivisionIndex < this.subdivisions; ++subdivisionIndex) {
aBarPiece = document.createElement('div');
aBarPiece.style.position = 'absolute';
aBarPiece.style.overflow = 'hidden';
aBarPiece.style.width = Math.round(subdivisionPixelLength) + 'px';
if((subdivisionIndex % 2) == 0) {
aBarPiece.className = 'sbBar';
aBarPiece.style.left = Math.round(xPosition - xOffsetBar) + 'px';
}
else {
aBarPiece.className = 'sbBarAlt';
aBarPiece.style.left = Math.round(xPosition - xOffsetBarAlt) + 'px';
}
aBarPiece.appendChild(document.createTextNode(' '));
this.graphicsContainer.appendChild(aBarPiece);
// add minor marker if not the last subdivision
if(subdivisionIndex < (this.subdivisions - 1)) {
// set xPosition and markerMeasure to end of subdivision
xPosition = ((divisionIndex * this.subdivisions) + (subdivisionIndex + 1)) * subdivisionPixelLength;
xPosition += alignmentOffset[this.align];
markerMeasure = (divisionIndex * this.subdivisions + subdivisionIndex + 1) * subdivisionDisplayLength;
aMarker = document.createElement('div');
aMarker.className = 'sbMarkerMinor';
aMarker.style.position = 'absolute';
aMarker.style.overflow = 'hidden';
aMarker.style.left = Math.round(xPosition - xOffsetMarkerMinor) + 'px';
aMarker.appendChild(document.createTextNode(' '));
this.graphicsContainer.appendChild(aMarker);
if(this.showMinorMeasures && !this.singleLine) {
// add corresponding measure
numbersBox = document.createElement('div');
numbersBox.className = 'sbNumbersBox';
numbersBox.style.position = 'absolute';
numbersBox.style.overflow = 'hidden';
numbersBox.style.textAlign = 'center';
numbersBox.style.width = Math.round(subdivisionPixelLength * 2) + 'px';
numbersBox.style.left = Math.round(xPosition - subdivisionPixelLength) + 'px';
numbersBox.appendChild(document.createTextNode(markerMeasure));
this.numbersContainer.appendChild(numbersBox);
}
}
}
}
// set xPosition and markerMeasure to end of divisions
xPosition = (this.divisions * this.subdivisions) * subdivisionPixelLength;
xPosition += alignmentOffset[this.align];
markerMeasure = ((this.divisions * this.subdivisions) * subdivisionDisplayLength).toFixed(numDec);
// add the final major marker
aMarker = document.createElement('div');
aMarker.className = 'sbMarkerMajor';
aMarker.style.position = 'absolute';
aMarker.style.overflow = 'hidden';
aMarker.style.left = Math.round(xPosition - xOffsetMarkerMajor) + 'px';
aMarker.appendChild(document.createTextNode(' '));
this.graphicsContainer.appendChild(aMarker);
// add final measure
if(!this.singleLine) {
numbersBox = document.createElement('div');
numbersBox.className = 'sbNumbersBox';
numbersBox.style.position = 'absolute';
numbersBox.style.overflow = 'hidden';
numbersBox.style.textAlign = 'center';
if(this.showMinorMeasures) {
numbersBox.style.width = Math.round(subdivisionPixelLength * 2) + 'px';
numbersBox.style.left = Math.round(xPosition - subdivisionPixelLength) + 'px';
}
else {
numbersBox.style.width = Math.round(this.subdivisions * subdivisionPixelLength * 2) + 'px';
numbersBox.style.left = Math.round(xPosition - (this.subdivisions * subdivisionPixelLength)) + 'px';
}
numbersBox.appendChild(document.createTextNode(markerMeasure));
this.numbersContainer.appendChild(numbersBox);
}
// add content to the label container
var labelBox = document.createElement('div');
labelBox.style.position = 'absolute';
var labelText;
if(this.singleLine) {
labelText = markerMeasure;
labelBox.className = 'sbLabelBoxSingleLine';
labelBox.style.top = '-0.6em';
labelBox.style.left = (xPosition + 10) + 'px';
}
else {
labelText = '';
labelBox.className = 'sbLabelBox';
labelBox.style.textAlign = 'center';
labelBox.style.width = Math.round(this.divisions * this.subdivisions * subdivisionPixelLength) + 'px';
labelBox.style.left = Math.round(alignmentOffset[this.align]) + 'px';
labelBox.style.overflow = 'hidden';
}
if(this.abbreviateLabel) {
labelText += ' ' + displayUnitsAbbr;
}
else {
labelText += ' ' + displayUnits;
}
labelBox.appendChild(document.createTextNode(labelText));
this.labelContainer.appendChild(labelBox);
// support for browsers without the Document.styleSheets property (Opera)
if(!document.styleSheets) {
// override custom css with default
var defaultStyle = document.createElement('style');
defaultStyle.type = 'text/css';
var styleText = '.sbBar {top: 0px; background: #666666; height: 1px; border: 0;}';
styleText += '.sbBarAlt {top: 0px; background: #666666; height: 1px; border: 0;}';
styleText += '.sbMarkerMajor {height: 7px; width: 1px; background: #666666; border: 0;}';
styleText += '.sbMarkerMinor {height: 5px; width: 1px; background: #666666; border: 0;}';
styleText += '.sbLabelBox {top: -16px;}';
styleText += '.sbNumbersBox {top: 7px;}';
defaultStyle.appendChild(document.createTextNode(styleText));
document.getElementsByTagName('head').item(0).appendChild(defaultStyle);
}
// append the child containers to the parent container
this.container.appendChild(this.graphicsContainer);
this.container.appendChild(this.labelContainer);
this.container.appendChild(this.numbersContainer);
};
ScaleBar.prototype.place = function(elementId) {
if(elementId == null) {
document.body.appendChild(this.container);
}
else {
var anElement = document.getElementById(elementId);
if(anElement != null) {
anElement.appendChild(this.container);
}
}
this.update();
};
var charset="";
/**********************************************************************
*
* $Id: kaRubberZoom.js,v 1.4 2006/07/20 12:04:32 lbecchi Exp $
*
* purpose: a rubber zoom.
*
* author: Lorenzo Becchi and Paul Spencer (pspencer@dmsolutions.ca) (bug 1494)
*
* TODO:
*
* -
*
**********************************************************************
*
* Copyright (c) 2005, DM Solutions Group Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
**********************************************************************
*
* To use this tool:
*
* 1) add a script tag to your page
*
*
*
* 2) create a new instance of kaRubberZoom
*
* myKaRubberZoom = new kaRubberZoom( myKaMap );
*
*
*****************************************************************************/
/**
* kaRubberZoom constructor
*
* construct a new kaRubberZoom object of a given type for a given kaMap instance
*
* oKaMap - a kaMap instance
*
* type - int, one of KAMAP_POINT_QUERY or KAMAP_RECT_QUERY. If the type is
* KAMAP_POINT_QUERY then only point queries are allowed. If the type
* is KAMAP_RECT_QUERY then point or rectangle queries are possible.
*/
function kaRubberZoom( oKaMap) {
kaTool.apply( this, [oKaMap] );
this.name = 'kaRubberZoom';
//this.cursor = 'help';
this.cursor = 'crosshair';
//this is the HTML element that is visible
this.domObj = document.createElement( 'div' );
this.domObj.style.position = 'absolute';
this.domObj.style.top = '0px';
this.domObj.style.left = '0px';
this.domObj.style.width = '1px';
this.domObj.style.height = '1px';
this.domObj.style.zIndex = 100;
this.domObj.style.visibility = 'hidden';
this.domObj.style.border = '1px solid blue';
this.domObj.style.backgroundColor = 'white';
this.domObj.style.opacity = 0.50;
this.domObj.style.mozOpacity = 0.50;
this.domObj.style.filter = 'Alpha(opacity=50)';
this.kaMap.theInsideLayer.appendChild( this.domObj );
this.startx = null;
this.starty = null;
this.endx = null;
this.endy = null;
this.bMouseDown = false;
this.RubberZooming = false;
this.dataOver = false;
for (var p in kaTool.prototype) {
if (!kaRubberZoom.prototype[p])
kaRubberZoom.prototype[p]= kaTool.prototype[p];
}
};
/*
* draw a box representing the query region.
*
* kaRubberZoom maintains the query region in four variables. The variables are
* assumed to be in pixel coordinates and are used to position the box. If
* any of the coordinates are null, clear the query box.
*/
kaRubberZoom.prototype.drawZoomBox = function() {
if (this.startx == null || this.starty == null ||
this.endx == null || this.endy == null ) {
this.domObj.style.visibility = 'hidden';
this.domObj.style.top = '0px';
this.domObj.style.left = '0px';
this.domObj.style.width = '1px';
this.domObj.style.height = '1px';
return;
}
this.domObj.style.visibility = 'visible';
if (this.endx < this.startx) {
this.domObj.style.left = (this.endx - this.kaMap.xOrigin) + 'px';
this.domObj.style.width = (this.startx - this.endx) + "px";
} else {
this.domObj.style.left = (this.startx - this.kaMap.xOrigin) + 'px';
this.domObj.style.width = (this.endx - this.startx) + "px";
}
if (this.endy < this.starty) {
this.domObj.style.top = (this.endy - this.kaMap.yOrigin) + 'px';
this.domObj.style.height = (this.starty - this.endy) + "px";
} else {
this.domObj.style.top = (this.starty - this.kaMap.yOrigin) + 'px';
this.domObj.style.height = (this.endy - this.starty) + "px";
}
};
/**
* kaRubberZoom.onmouseout( e )
*
* called when the mouse leaves theInsideLayer. Terminate the query
*
* e - object, the event object or null (in ie)
*/
kaRubberZoom.prototype.onmouseout = function(e) {
e = (e)?e:((event)?event:null);
if (!e.target) e.target = e.srcElement;
if (e.target.id == this.kaMap.domObj.id) {
this.bMouseDown = false;
this.RubberZooming = false;
this.startx = this.endx = this.starty = this.endy = null;
this.drawZoomBox();
return kaTool.prototype.onmouseout.apply(this, [e]);
}
};
/**
* kaRubberZoom.onmousemove( e )
*
* called when the mouse moves over theInsideLayer.
*
* e - object, the event object or null (in ie)
*/
kaRubberZoom.prototype.onmousemove = function(e) {
e = (e)?e:((event)?event:null);
if (!this.bMouseDown) {
this.RubberZooming = false;
return false;
}
var x = e.pageX || (e.clientX +
(document.documentElement.scrollLeft || document.body.scrollLeft));
var y = e.pageY || (e.clientY +
(document.documentElement.scrollTop || document.body.scrollTop));
//if (this.type == KAMAP_RECT_QUERY) {
var aPixPos = this.adjustPixPosition( x, y );
this.endx=-aPixPos[0];
this.endy=-aPixPos[1];
this.drawZoomBox();
// }
return false;
}
;
/**
* kaRubberZoom.onmousedown( e )
*
* called when a mouse button is pressed over theInsideLayer.
*
* e - object, the event object or null (in ie)
*/
kaRubberZoom.prototype.onmousedown = function(e) {
e = (e)?e:((event)?event:null);
if(this.dataOver){
return;
}
if (e.button==2) {
return this.cancelEvent(e);
} else {
if (this.kaMap.isIE4) document.onkeydown = kaTool_redirect_onkeypress;
document.onkeypress = kaTool_redirect_onkeypress;
this.bMouseDown=true;
this.RubberZooming = true;
var x = e.pageX || (e.clientX +
(document.documentElement.scrollLeft || document.body.scrollLeft));
var y = e.pageY || (e.clientY +
(document.documentElement.scrollTop || document.body.scrollTop));
var aPixPos = this.adjustPixPosition( x,y );
this.startx=this.endx=-aPixPos[0];
this.starty=this.endy=-aPixPos[1];
this.drawZoomBox();
e.cancelBubble = true;
e.returnValue = false;
if (e.stopPropogation) e.stopPropogation();
if (e.preventDefault) e.preventDefault();
return false;
}
};
/**
* kaRubberZoom.onmouseup( e )
*
* called when a mouse button is clicked over theInsideLayer.
*
* e - object, the event object or null (in ie)
*/
kaRubberZoom.prototype.onmouseup = function(e) {
e = (e)?e:((event)?event:null);
if(this.dataOver){
return;
}
var type = KAMAP_POINT_QUERY;
var start = this.kaMap.pixToGeo( -this.startx, -this.starty );
var coords = start;
if (this.startx!=this.endx&&this.starty!=this.endy) {
type = KAMAP_RECT_QUERY;
coords = start.concat(this.kaMap.pixToGeo( -this.endx, -this.endy ));
if(coords[2] < coords[0]) {
//minx gt maxx than I invert values
var minx = coords[2];
var maxx = coords[0];
coords[0] = minx;
coords[2] = maxx;
}
if(coords[1] < coords[3]){
//miny gt maggiore than I invert values
var miny = coords[1];
var maxy = coords[3];
coords[3] = miny;
coords[1] = maxy;
}
}
//this.kaMap.triggerEvent(KAMAP_QUERY, type, coords);
this.startx = this.endx = this.starty = this.endy = null;
this.drawZoomBox();
//(minx, miny, maxx, maxy)
if(coords[2] && coords[0] && coords[3] && coords[1]){
//Rubber Zoom
this.kaMap.zoomToExtents(coords[0],coords[1],coords[2],coords[3] );
} else if (coords[0] && coords[1]){
//single click
this.kaMap.zoomIn();
this.kaMap.zoomTo(coords[0],coords[1]);
}
this.RubberZooming = false;
return false;
};var charset="";
/**********************************************************************
*
* $Id: kaMouseTracker.js,v 1.1 2006/07/20 13:47:11 pspencer Exp $
*
* purpose: a simple tool for tracking mouse movement over the map
*
* author: Paul Spencer (pspencer@dmsolutions.ca)
*
**********************************************************************
*
* Copyright (c) 2005, DM Solutions Group Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
**********************************************************************
*
* To use this tool:
*
* 1) add a script tag to your page
*
*
*
* 2) create a new instance of kaMouseTracker
*
* myTracker = new kaMouseTracker( myKaMap );
* myTracker.activate();
*
* 3) listen for the tracker event
*
* myKaMap.registerForEvent( KAMAP_MOUSE_TRACKER, null, myMouseMoved );
*
* 4) and do something when the user requests a query
*
* function myMouseMoved( eventID, coords )
* {
* var pos = 'lon: ' + coords.x + ', lat: ' + coords.y;
* document.getElementById('mousePosition').innerHTML = pos;
* }
*
* Mouse position is reported in the coordinate system of the map.
*
*****************************************************************************/
// the mouse tracker event id
var KAMAP_MOUSE_TRACKER = gnLastEventId ++;
/**
* kaMouseTracker constructor
*
* construct a new kaMouseTracker object for a given kaMap instance
*
* oKaMap - a kaMap instance
*/
function kaMouseTracker( oKaMap ) {
kaTool.apply( this, [oKaMap] );
this.name = 'kaMouseTracker';
this.bInfoTool = true;
for (var p in kaTool.prototype) {
if (!kaMouseTracker.prototype[p])
kaMouseTracker.prototype[p]= kaTool.prototype[p];
}
};
/**
* kaMouseTracker.onmousemove( e )
*
* called when the mouse moves over theInsideLayer.
*
* e - object, the event object or null (in ie)
*/
kaMouseTracker.prototype.onmousemove = function(e) {
e = (e)?e:((event)?event:null);
var x = e.pageX || (e.clientX +
(document.documentElement.scrollLeft || document.body.scrollLeft));
var y = e.pageY || (e.clientY +
(document.documentElement.scrollTop || document.body.scrollTop));
var a = this.adjustPixPosition( x,y );
var p = this.kaMap.pixToGeo( a[0], a[1] );
this.kaMap.triggerEvent(KAMAP_MOUSE_TRACKER, {x:p[0], y:p[1]});
return false;
};var charset="";
/**********************************************************************
*
* $Id: kaSearch.js,v 1.2 2006/08/08 20:50:41 lbecchi Exp $
*
* purpose: search system for ka-Map (bug 1509)
*
*
* author: Paul Spencer, Lorenzo Becchi & Andrea Cappugi
*
* TODO:
* -
*
**********************************************************************
*
* Copyright (c) 2006, ominiverdi.org
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
**********************************************************************/
/******************************************************************************
* kaSearch -
*
* To use kaSearch:
*
* 1) add a script tag to your page:
*
*
*
* 2) create a new instance of kaSearch
*
* var toolTip = new kaSearch( oMap);
*
*
*
*
*
*****************************************************************************/
function kaSearch( oKaMap ){
this.kaMap = oKaMap;
this.image = null;
this.domObj = null;
this.tooltip = new kaToolTip(oKaMap);
this.init();
};
kaSearch.prototype.init = function(){
this.tooltip.setTipImage(this.kaMap.server + 'common/images2/tip-yellow.png',-6,-19);
};
kaSearch.prototype.search=function(search_query){
if (search_query.length <= 0){
alert("Input search string!");
}
if (search_query.length > 0)
{
var agt = navigator.userAgent.toLowerCase();
var is_ie = (agt.indexOf('msie') != -1);
var is_ie5 = (agt.indexOf('msie 5') != -1);
element = document.getElementById ('searchres');
element.innerHTML = "Processing search. Please wait... ";
element.className = "visible";
function handle_do_search ()
{
if (xmlhttp.readyState == 4)//request completed
{
if (xmlhttp.status == 200)//request successful
{
element.innerHTML = xmlhttp.responseText;
}
else
{
alert ('No server answer!');
}
}
}
var xmlhttp = null;
if (is_ie)
{
var control = (is_ie5) ? "Microsoft.XMLHTTP" : "Msxml2.XMLHTTP";
try
{
xmlhttp = new ActiveXObject(control);
xmlhttp.onreadystatechange = handle_do_search;
} catch(e)
{
alert("You need to enable active scripting and activeX controls");
}
}
else
{
xmlhttp = new XMLHttpRequest();
xmlhttp.onload = handle_do_search;
xmlhttp.onerror = handle_do_search;
}
//call for xsearch.phtml results - sending link
searchstring=encodeURIComponent(search_query);// encoding searchstring for link
xmlhttp.open('GET', "tools/search/kaSearch.phtml?xmlRequest=true&map="+this.kaMap.getCurrentMap().name+"&searchstring="+searchstring, true);
xmlhttp.send(null);
}
};
var charset="";
/**********************************************************************
*
* $Id: kaToolTip.js,v 1.3 2006/08/08 20:51:35 lbecchi Exp $
*
* purpose: manage simple tool tips for ka-Map (bug 1374)
*
*
* author: Lorenzo Becchi & Andrea Cappugi
*
* TODO:
* -
*
**********************************************************************
*
* Copyright (c) 2006, ominiverdi.org
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
**********************************************************************/
/******************************************************************************
* kaToolTip -
*
* To use kaToolTip:
*
* 1) add a script tag to your page:
*
*
*
* 2) create a new instance of kaToolTip
*
* var toolTip = new kaToolTip( oMap);
*
* 3) if you want you can set an image (as the tip pointer)
*
* var offsetX=-6;//offset to move the image left-right
* var offsetY=-19;//offset to move the image top-bottom
* toolTip.setTipImage('images/tip-red.png',offsetX,offsetY);
*
* 4) Set text
*
* toolTip.setText('Some text inside the tooltip');
*
* 6) add it to the map
*
* toolTip.move(x,y); //pixel coords
*
* or by geo coords:
*
* toolTip.moveGeo(x,y); //geo coords
*
* 7) hide the tooltip
*
* toolTip.move();
*
*
*
*
*****************************************************************************/
function kaToolTip( oKaMap ){
this.kaMap = oKaMap;
this.image = null;
this.domObj = null;
this.viewport = this.kaMap.domObj;
this.visible= false;
this.init();
};
/**
* wmsLayer.addRequestParameter( name, parameter )
*
* add a parameter to the baseURL safely by checking to see if the parameter
* exists already. This is an internal function not intended to be used
* by other code.
*/
kaToolTip.prototype.init = function(){
this.domObj = document.createElement('div');
this.domObj.setAttribute('id', 'toolTip');
this.minZindex = 1;
this.coordX = null;
this.coordY = null;
this.viewport.appendChild(this.domObj);
this.domObj.style.position='absolute';
/*Style features*/
this.move();
this.domObj.toolTip=this;
this.domObj.style.zIndex=this.minZindex;
/*Position features*/
//this.domObj.onclick=this.onclick;
this.setText('Wait a moment please!');
this.kaMap.registerForEvent( KAMAP_MAP_CLICKED, this, this.onclick );
this.kaMap.registerForEvent( KAMAP_EXTENTS_CHANGED, this, this.extentChanged );
};
kaToolTip.prototype.onclick=function(e){
e = (e)?e:((event)?event:null);
this.move();
};
kaToolTip.prototype.setText = function(text){
this.domObj.innerHTML = text;
};
kaToolTip.prototype.setTipImage = function(url,offsetX,offsetY){
offsetX = (offsetX)?offsetX:0;
offsetY = (offsetX)?offsetY:0;
image = document.createElement('img');
image.src=url;
image.setAttribute('id', 'toolTipImage');
image.style.position='absolute';
image.style.zIndex=this.minZindex++;
image.style.top='-200px';
image.style.left='-200px';
image.offsetX=offsetX;
image.offsetY=offsetY;
this.image = image;
this.viewport.appendChild(image);
};
//move the tooltip using geo coords
kaToolTip.prototype.moveGeo = function(){
//(int [x],int [y])
var x = parseInt(arguments[0]);
var y = parseInt(arguments[1]);
var pixPos = this.kaMap.geoToPix(x,y);
var nPixPos = this.kaMap.currentTool.adjustPixPosition( pixPos[0]*(-1), pixPos[1]*(-1) );
var newX =nPixPos[0];
var newY = nPixPos[1];
this.move(newX,newY);
};
//move the tooltip in pixel space
kaToolTip.prototype.move = function(){
// (int [x],int [y],bool [noRecenter])
var x = 0;
var y = 0;
var aPixPos = 0;
var geoPix = 0;
var noRecenter = false;
if(arguments.length<2){
/*original position*/
//this.domObj.style.top='-'+getObjectHeight(this.domObj)+'px';
//this.domObj.style.left= '-'+getObjectWidth(this.domObj)+'px';
this.visible = false;
this.domObj.style.top='-10000px';
this.domObj.style.left= '-10000px';
aPixPos = this.kaMap.currentTool.adjustPixPosition( parseInt(x) , parseInt(y) );
var geoCoords = this.kaMap.pixToGeo( aPixPos[0],aPixPos[1]);
this.coordX = geoCoords[0];
this.coordY = geoCoords[1];
//if(this.image)this.image.style.top = '-'+getObjectHeight(this.domObj)+'px';
//if(this.image)this.image.style.left = '-'+getObjectWidth(this.domObj)+'px';
if(this.image)this.image.style.top = '-100000px';
if(this.image)this.image.style.left = '-100000px';
//alert('move to 0');
} else {
x = parseInt(arguments[0]);
y = parseInt(arguments[1]);
this.visible = true;
//alert('move to:' + x +' ' + y);
aPixPos = this.kaMap.currentTool.adjustPixPosition( parseInt(x) , parseInt(y) );
var geoCoords = this.kaMap.pixToGeo( aPixPos[0],aPixPos[1]);
this.coordX = geoCoords[0];
this.coordY = geoCoords[1];
//alert('coords: '+this.coordX + ' ' +this.coordY);
this.domObj.style.top=y-10+'px';//
this.domObj.style.left=x-(getObjectWidth(this.domObj)/2)+'px';
if(this.image)this.image.style.top = (y+this.image.offsetY)+'px';
if(this.image)this.image.style.left = (x+this.image.offsetX)+'px';
//adesso calcolo se il div sta dentro il viewport
if((arguments[2])&&arguments[2]==true)noRecenter = true;
if(!noRecenter)this.recenter(this.domObj);
}
};
kaToolTip.prototype.adjustPosition = function(x,y){
var ny =parseInt(this.domObj.style.top)+y;
var nx =parseInt(this.domObj.style.left)+x;
this.domObj.style.top=ny+'px';//
this.domObj.style.left=nx+'px';
if(this.image)this.image.style.top = (parseInt(this.image.style.top)+y)+'px';
if(this.image)this.image.style.left =(parseInt(this.image.style.left)+x)+'px';
};
kaToolTip.prototype.recenter=function(tip){
//misuro le diemensioni in pix del tip
var tipWidth = getObjectWidth(tip);
var tipHeight = getObjectHeight(tip);
var tipTop = parseInt(tip.style.top);
var tipLeft= parseInt(tip.style.left);
//prendo i dati del viewport
var viewportWheight = tip.toolTip.kaMap.viewportHeight;
var viewportWidth = tip.toolTip.kaMap.viewportWidth;
//calcolo le posizioni di ogni angolo del tip sul viewport
var topSlide=1;
var leftSlide=1;
if((tipTop+tipHeight)>viewportWheight) topSlide=(tipTop+tipHeight)-viewportWheight;
if((tipLeft+tipWidth)>viewportWidth) leftSlide=(tipLeft+tipWidth)-viewportWidth;
if(tipLeft<0) leftSlide=tipLeft-20;
if(tipTop<0) topSlide=tipTop-20;
if(topSlide!=1 || leftSlide!=1){
tip.toolTip.kaMap.slideBy(-(leftSlide+10), -(topSlide+10));
tip.toolTip.adjustPosition(-(leftSlide+10), -(topSlide+10));
}
};
kaToolTip.prototype.extentChanged=function(){
var pixPos = this.kaMap.geoToPix(this.coordX,this.coordY);
var nPixPos = this.kaMap.currentTool.adjustPixPosition( pixPos[0]*(-1), pixPos[1]*(-1) );
var newX =nPixPos[0];
var newY = nPixPos[1];
if(this.visible)this.move(newX,newY,true);
};
function encodeMyHtml(string) {
encodedHtml = escape(string);
encodedHtml = encodedHtml.replace("/","%2F");
encodedHtml = encodedHtml.replace(/\?/g,"%3F");
encodedHtml = encodedHtml.replace(/=/g,"%3D");
encodedHtml = encodedHtml.replace(/&/g,"%26");
encodedHtml = encodedHtml.replace(/@/g,"%40");
return encodedHtml;
};
function urlDecode(sz){
return unescape(sz).replace(/\+/g," ");
};
var charset="";
// Copyright 2006 Google Inc.
//
// 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.
// Known Issues:
//
// * Patterns are not implemented.
// * Radial gradient are not implemented. The VML version of these look very
// different from the canvas one.
// * Clipping paths are not implemented.
// * Coordsize. The width and height attribute have higher priority than the
// width and height style values which isn't correct.
// * Painting mode isn't implemented.
// * Canvas width/height should is using content-box by default. IE in
// Quirks mode will draw the canvas using border-box. Either change your
// doctype to HTML5
// (http://www.whatwg.org/specs/web-apps/current-work/#the-doctype)
// or use Box Sizing Behavior from WebFX
// (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html)
// * Non uniform scaling does not correctly scale strokes.
// * Optimize. There is always room for speed improvements.
// Only add this code if we do not already have a canvas implementation
if (!document.createElement('canvas').getContext) {
(function() {
// alias some functions to make (compiled) code shorter
var m = Math;
var mr = m.round;
var ms = m.sin;
var mc = m.cos;
var abs = m.abs;
var sqrt = m.sqrt;
// this is used for sub pixel precision
var Z = 10;
var Z2 = Z / 2;
/**
* This funtion is assigned to the elements as element.getContext().
* @this {HTMLElement}
* @return {CanvasRenderingContext2D_}
*/
function getContext() {
return this.context_ ||
(this.context_ = new CanvasRenderingContext2D_(this));
}
var slice = Array.prototype.slice;
/**
* Binds a function to an object. The returned function will always use the
* passed in {@code obj} as {@code this}.
*
* Example:
*
* g = bind(f, obj, a, b)
* g(c, d) // will do f.call(obj, a, b, c, d)
*
* @param {Function} f The function to bind the object to
* @param {Object} obj The object that should act as this when the function
* is called
* @param {*} var_args Rest arguments that will be used as the initial
* arguments when the function is called
* @return {Function} A new function that has bound this
*/
function bind(f, obj, var_args) {
var a = slice.call(arguments, 2);
return function() {
return f.apply(obj, a.concat(slice.call(arguments)));
};
}
var G_vmlCanvasManager_ = {
init: function(opt_doc) {
if (/MSIE/.test(navigator.userAgent) && !window.opera) {
var doc = opt_doc || document;
// Create a dummy element so that IE will allow canvas elements to be
// recognized.
doc.createElement('canvas');
doc.attachEvent('onreadystatechange', bind(this.init_, this, doc));
}
},
init_: function(doc) {
// create xmlns
if (!doc.namespaces['g_vml_']) {
doc.namespaces.add('g_vml_', 'urn:schemas-microsoft-com:vml',
'#default#VML');
}
if (!doc.namespaces['g_o_']) {
doc.namespaces.add('g_o_', 'urn:schemas-microsoft-com:office:office',
'#default#VML');
}
// Setup default CSS. Only add one style sheet per document
if (!doc.styleSheets['ex_canvas_']) {
var ss = doc.createStyleSheet();
ss.owningElement.id = 'ex_canvas_';
ss.cssText = 'canvas{display:inline-block;overflow:hidden;' +
// default size is 300x150 in Gecko and Opera
'text-align:left;width:300px;height:150px}' +
'g_vml_\\:*{behavior:url(#default#VML)}' +
'g_o_\\:*{behavior:url(#default#VML)}';
}
// find all canvas elements
var els = doc.getElementsByTagName('canvas');
for (var i = 0; i < els.length; i++) {
this.initElement(els[i]);
}
},
/**
* Public initializes a canvas element so that it can be used as canvas
* element from now on. This is called automatically before the page is
* loaded but if you are creating elements using createElement you need to
* make sure this is called on the element.
* @param {HTMLElement} el The canvas element to initialize.
* @return {HTMLElement} the element that was created.
*/
initElement: function(el) {
if (!el.getContext) {
el.getContext = getContext;
// Remove fallback content. There is no way to hide text nodes so we
// just remove all childNodes. We could hide all elements and remove
// text nodes but who really cares about the fallback content.
el.innerHTML = '';
// do not use inline function because that will leak memory
el.attachEvent('onpropertychange', onPropertyChange);
el.attachEvent('onresize', onResize);
var attrs = el.attributes;
if (attrs.width && attrs.width.specified) {
// TODO: use runtimeStyle and coordsize
// el.getContext().setWidth_(attrs.width.nodeValue);
el.style.width = attrs.width.nodeValue + 'px';
} else {
el.width = el.clientWidth;
}
if (attrs.height && attrs.height.specified) {
// TODO: use runtimeStyle and coordsize
// el.getContext().setHeight_(attrs.height.nodeValue);
el.style.height = attrs.height.nodeValue + 'px';
} else {
el.height = el.clientHeight;
}
//el.getContext().setCoordsize_()
}
return el;
}
};
function onPropertyChange(e) {
var el = e.srcElement;
switch (e.propertyName) {
case 'width':
el.style.width = el.attributes.width.nodeValue + 'px';
el.getContext().clearRect();
break;
case 'height':
el.style.height = el.attributes.height.nodeValue + 'px';
el.getContext().clearRect();
break;
}
}
function onResize(e) {
var el = e.srcElement;
if (el.firstChild) {
el.firstChild.style.width = el.clientWidth + 'px';
el.firstChild.style.height = el.clientHeight + 'px';
}
}
G_vmlCanvasManager_.init();
// precompute "00" to "FF"
var dec2hex = [];
for (var i = 0; i < 16; i++) {
for (var j = 0; j < 16; j++) {
dec2hex[i * 16 + j] = i.toString(16) + j.toString(16);
}
}
function createMatrixIdentity() {
return [
[1, 0, 0],
[0, 1, 0],
[0, 0, 1]
];
}
function matrixMultiply(m1, m2) {
var result = createMatrixIdentity();
for (var x = 0; x < 3; x++) {
for (var y = 0; y < 3; y++) {
var sum = 0;
for (var z = 0; z < 3; z++) {
sum += m1[x][z] * m2[z][y];
}
result[x][y] = sum;
}
}
return result;
}
function copyState(o1, o2) {
o2.fillStyle = o1.fillStyle;
o2.lineCap = o1.lineCap;
o2.lineJoin = o1.lineJoin;
o2.lineWidth = o1.lineWidth;
o2.miterLimit = o1.miterLimit;
o2.shadowBlur = o1.shadowBlur;
o2.shadowColor = o1.shadowColor;
o2.shadowOffsetX = o1.shadowOffsetX;
o2.shadowOffsetY = o1.shadowOffsetY;
o2.strokeStyle = o1.strokeStyle;
o2.globalAlpha = o1.globalAlpha;
o2.arcScaleX_ = o1.arcScaleX_;
o2.arcScaleY_ = o1.arcScaleY_;
o2.lineScale_ = o1.lineScale_;
}
function processStyle(styleString) {
var str, alpha = 1;
styleString = String(styleString);
if (styleString.substring(0, 3) == 'rgb') {
var start = styleString.indexOf('(', 3);
var end = styleString.indexOf(')', start + 1);
var guts = styleString.substring(start + 1, end).split(',');
str = '#';
for (var i = 0; i < 3; i++) {
str += dec2hex[Number(guts[i])];
}
if (guts.length == 4 && styleString.substr(3, 1) == 'a') {
alpha = guts[3];
}
} else {
str = styleString;
}
return {color: str, alpha: alpha};
}
function processLineCap(lineCap) {
switch (lineCap) {
case 'butt':
return 'flat';
case 'round':
return 'round';
case 'square':
default:
return 'square';
}
}
/**
* This class implements CanvasRenderingContext2D interface as described by
* the WHATWG.
* @param {HTMLElement} surfaceElement The element that the 2D context should
* be associated with
*/
function CanvasRenderingContext2D_(surfaceElement) {
this.m_ = createMatrixIdentity();
this.mStack_ = [];
this.aStack_ = [];
this.currentPath_ = [];
// Canvas context properties
this.strokeStyle = '#000';
this.fillStyle = '#000';
this.lineWidth = 1;
this.lineJoin = 'miter';
this.lineCap = 'butt';
this.miterLimit = Z * 1;
this.globalAlpha = 1;
this.canvas = surfaceElement;
var el = surfaceElement.ownerDocument.createElement('div');
el.style.width = surfaceElement.clientWidth + 'px';
el.style.height = surfaceElement.clientHeight + 'px';
el.style.overflow = 'hidden';
el.style.position = 'absolute';
surfaceElement.appendChild(el);
this.element_ = el;
this.arcScaleX_ = 1;
this.arcScaleY_ = 1;
this.lineScale_ = 1;
}
var contextPrototype = CanvasRenderingContext2D_.prototype;
contextPrototype.clearRect = function() {
this.element_.innerHTML = '';
};
contextPrototype.beginPath = function() {
// TODO: Branch current matrix so that save/restore has no effect
// as per safari docs.
this.currentPath_ = [];
};
contextPrototype.moveTo = function(aX, aY) {
var p = this.getCoords_(aX, aY);
this.currentPath_.push({type: 'moveTo', x: p.x, y: p.y});
this.currentX_ = p.x;
this.currentY_ = p.y;
};
contextPrototype.lineTo = function(aX, aY) {
var p = this.getCoords_(aX, aY);
this.currentPath_.push({type: 'lineTo', x: p.x, y: p.y});
this.currentX_ = p.x;
this.currentY_ = p.y;
};
contextPrototype.bezierCurveTo = function(aCP1x, aCP1y,
aCP2x, aCP2y,
aX, aY) {
var p = this.getCoords_(aX, aY);
var cp1 = this.getCoords_(aCP1x, aCP1y);
var cp2 = this.getCoords_(aCP2x, aCP2y);
bezierCurveTo(this, cp1, cp2, p);
};
// Helper function that takes the already fixed cordinates.
function bezierCurveTo(self, cp1, cp2, p) {
self.currentPath_.push({
type: 'bezierCurveTo',
cp1x: cp1.x,
cp1y: cp1.y,
cp2x: cp2.x,
cp2y: cp2.y,
x: p.x,
y: p.y
});
self.currentX_ = p.x;
self.currentY_ = p.y;
}
contextPrototype.quadraticCurveTo = function(aCPx, aCPy, aX, aY) {
// the following is lifted almost directly from
// http://developer.mozilla.org/en/docs/Canvas_tutorial:Drawing_shapes
var cp = this.getCoords_(aCPx, aCPy);
var p = this.getCoords_(aX, aY);
var cp1 = {
x: this.currentX_ + 2.0 / 3.0 * (cp.x - this.currentX_),
y: this.currentY_ + 2.0 / 3.0 * (cp.y - this.currentY_)
};
var cp2 = {
x: cp1.x + (p.x - this.currentX_) / 3.0,
y: cp1.y + (p.y - this.currentY_) / 3.0
};
bezierCurveTo(this, cp1, cp2, p);
};
contextPrototype.arc = function(aX, aY, aRadius,
aStartAngle, aEndAngle, aClockwise) {
aRadius *= Z;
var arcType = aClockwise ? 'at' : 'wa';
var xStart = aX + mc(aStartAngle) * aRadius - Z2;
var yStart = aY + ms(aStartAngle) * aRadius - Z2;
var xEnd = aX + mc(aEndAngle) * aRadius - Z2;
var yEnd = aY + ms(aEndAngle) * aRadius - Z2;
// IE won't render arches drawn counter clockwise if xStart == xEnd.
if (xStart == xEnd && !aClockwise) {
xStart += 0.125; // Offset xStart by 1/80 of a pixel. Use something
// that can be represented in binary
}
var p = this.getCoords_(aX, aY);
var pStart = this.getCoords_(xStart, yStart);
var pEnd = this.getCoords_(xEnd, yEnd);
this.currentPath_.push({type: arcType,
x: p.x,
y: p.y,
radius: aRadius,
xStart: pStart.x,
yStart: pStart.y,
xEnd: pEnd.x,
yEnd: pEnd.y});
};
contextPrototype.rect = function(aX, aY, aWidth, aHeight) {
this.moveTo(aX, aY);
this.lineTo(aX + aWidth, aY);
this.lineTo(aX + aWidth, aY + aHeight);
this.lineTo(aX, aY + aHeight);
this.closePath();
};
contextPrototype.strokeRect = function(aX, aY, aWidth, aHeight) {
var oldPath = this.currentPath_;
this.beginPath();
this.moveTo(aX, aY);
this.lineTo(aX + aWidth, aY);
this.lineTo(aX + aWidth, aY + aHeight);
this.lineTo(aX, aY + aHeight);
this.closePath();
this.stroke();
this.currentPath_ = oldPath;
};
contextPrototype.fillRect = function(aX, aY, aWidth, aHeight) {
var oldPath = this.currentPath_;
this.beginPath();
this.moveTo(aX, aY);
this.lineTo(aX + aWidth, aY);
this.lineTo(aX + aWidth, aY + aHeight);
this.lineTo(aX, aY + aHeight);
this.closePath();
this.fill();
this.currentPath_ = oldPath;
};
contextPrototype.createLinearGradient = function(aX0, aY0, aX1, aY1) {
var gradient = new CanvasGradient_('gradient');
gradient.x0_ = aX0;
gradient.y0_ = aY0;
gradient.x1_ = aX1;
gradient.y1_ = aY1;
return gradient;
};
contextPrototype.createRadialGradient = function(aX0, aY0, aR0,
aX1, aY1, aR1) {
var gradient = new CanvasGradient_('gradientradial');
gradient.x0_ = aX0;
gradient.y0_ = aY0;
gradient.r0_ = aR0;
gradient.x1_ = aX1;
gradient.y1_ = aY1;
gradient.r1_ = aR1;
return gradient;
};
contextPrototype.drawImage = function(image, var_args) {
var dx, dy, dw, dh, sx, sy, sw, sh;
// to find the original width we overide the width and height
var oldRuntimeWidth = image.runtimeStyle.width;
var oldRuntimeHeight = image.runtimeStyle.height;
image.runtimeStyle.width = 'auto';
image.runtimeStyle.height = 'auto';
// get the original size
var w = image.width;
var h = image.height;
// and remove overides
image.runtimeStyle.width = oldRuntimeWidth;
image.runtimeStyle.height = oldRuntimeHeight;
if (arguments.length == 3) {
dx = arguments[1];
dy = arguments[2];
sx = sy = 0;
sw = dw = w;
sh = dh = h;
} else if (arguments.length == 5) {
dx = arguments[1];
dy = arguments[2];
dw = arguments[3];
dh = arguments[4];
sx = sy = 0;
sw = w;
sh = h;
} else if (arguments.length == 9) {
sx = arguments[1];
sy = arguments[2];
sw = arguments[3];
sh = arguments[4];
dx = arguments[5];
dy = arguments[6];
dw = arguments[7];
dh = arguments[8];
} else {
throw Error('Invalid number of arguments');
}
var d = this.getCoords_(dx, dy);
var w2 = sw / 2;
var h2 = sh / 2;
var vmlStr = [];
var W = 10;
var H = 10;
// For some reason that I've now forgotten, using divs didn't work
vmlStr.push(' ' ,
' ',
' ');
this.element_.insertAdjacentHTML('BeforeEnd',
vmlStr.join(''));
};
contextPrototype.stroke = function(aFill) {
var lineStr = [];
var lineOpen = false;
var a = processStyle(aFill ? this.fillStyle : this.strokeStyle);
var color = a.color;
var opacity = a.alpha * this.globalAlpha;
var W = 10;
var H = 10;
lineStr.push('');
if (!aFill) {
var lineWidth = this.lineScale_ * this.lineWidth;
// VML cannot correctly render a line if the width is less than 1px.
// In that case, we dilute the color to make the line look thinner.
if (lineWidth < 1) {
opacity *= lineWidth;
}
lineStr.push(
' '
);
} else if (typeof this.fillStyle == 'object') {
var fillStyle = this.fillStyle;
var angle = 0;
var focus = {x: 0, y: 0};
// additional offset
var shift = 0;
// scale factor for offset
var expansion = 1;
if (fillStyle.type_ == 'gradient') {
var x0 = fillStyle.x0_ / this.arcScaleX_;
var y0 = fillStyle.y0_ / this.arcScaleY_;
var x1 = fillStyle.x1_ / this.arcScaleX_;
var y1 = fillStyle.y1_ / this.arcScaleY_;
var p0 = this.getCoords_(x0, y0);
var p1 = this.getCoords_(x1, y1);
var dx = p1.x - p0.x;
var dy = p1.y - p0.y;
angle = Math.atan2(dx, dy) * 180 / Math.PI;
// The angle should be a non-negative number.
if (angle < 0) {
angle += 360;
}
// Very small angles produce an unexpected result because they are
// converted to a scientific notation string.
if (angle < 1e-6) {
angle = 0;
}
} else {
var p0 = this.getCoords_(fillStyle.x0_, fillStyle.y0_);
var width = max.x - min.x;
var height = max.y - min.y;
focus = {
x: (p0.x - min.x) / width,
y: (p0.y - min.y) / height
};
width /= this.arcScaleX_ * Z;
height /= this.arcScaleY_ * Z;
var dimension = m.max(width, height);
shift = 2 * fillStyle.r0_ / dimension;
expansion = 2 * fillStyle.r1_ / dimension - shift;
}
// We need to sort the color stops in ascending order by offset,
// otherwise IE won't interpret it correctly.
var stops = fillStyle.colors_;
stops.sort(function(cs1, cs2) {
return cs1.offset - cs2.offset;
});
var length = stops.length;
var color1 = stops[0].color;
var color2 = stops[length - 1].color;
var opacity1 = stops[0].alpha * this.globalAlpha;
var opacity2 = stops[length - 1].alpha * this.globalAlpha;
var colors = [];
for (var i = 0; i < length; i++) {
var stop = stops[i];
colors.push(stop.offset * expansion + shift + ' ' + stop.color);
}
// When colors attribute is used, the meanings of opacity and o:opacity2
// are reversed.
lineStr.push(' ');
} else {
lineStr.push(' ');
}
lineStr.push(' ');
this.element_.insertAdjacentHTML('beforeEnd', lineStr.join(''));
};
contextPrototype.fill = function() {
this.stroke(true);
}
contextPrototype.closePath = function() {
this.currentPath_.push({type: 'close'});
};
/**
* @private
*/
contextPrototype.getCoords_ = function(aX, aY) {
var m = this.m_;
return {
x: Z * (aX * m[0][0] + aY * m[1][0] + m[2][0]) - Z2,
y: Z * (aX * m[0][1] + aY * m[1][1] + m[2][1]) - Z2
}
};
contextPrototype.save = function() {
var o = {};
copyState(this, o);
this.aStack_.push(o);
this.mStack_.push(this.m_);
this.m_ = matrixMultiply(createMatrixIdentity(), this.m_);
};
contextPrototype.restore = function() {
copyState(this.aStack_.pop(), this);
this.m_ = this.mStack_.pop();
};
function matrixIsFinite(m) {
for (var j = 0; j < 3; j++) {
for (var k = 0; k < 2; k++) {
if (!isFinite(m[j][k]) || isNaN(m[j][k])) {
return false;
}
}
}
return true;
}
function setM(ctx, m, updateLineScale) {
if (!matrixIsFinite(m)) {
return;
}
ctx.m_ = m;
if (updateLineScale) {
// Get the line scale.
// Determinant of this.m_ means how much the area is enlarged by the
// transformation. So its square root can be used as a scale factor
// for width.
var det = m[0][0] * m[1][1] - m[0][1] * m[1][0];
ctx.lineScale_ = sqrt(abs(det));
}
}
contextPrototype.translate = function(aX, aY) {
var m1 = [
[1, 0, 0],
[0, 1, 0],
[aX, aY, 1]
];
setM(this, matrixMultiply(m1, this.m_), false);
};
contextPrototype.rotate = function(aRot) {
var c = mc(aRot);
var s = ms(aRot);
var m1 = [
[c, s, 0],
[-s, c, 0],
[0, 0, 1]
];
setM(this, matrixMultiply(m1, this.m_), false);
};
contextPrototype.scale = function(aX, aY) {
this.arcScaleX_ *= aX;
this.arcScaleY_ *= aY;
var m1 = [
[aX, 0, 0],
[0, aY, 0],
[0, 0, 1]
];
setM(this, matrixMultiply(m1, this.m_), true);
};
contextPrototype.transform = function(m11, m12, m21, m22, dx, dy) {
var m1 = [
[m11, m12, 0],
[m21, m22, 0],
[dx, dy, 1]
];
setM(this, matrixMultiply(m1, this.m_), true);
};
contextPrototype.setTransform = function(m11, m12, m21, m22, dx, dy) {
var m = [
[m11, m12, 0],
[m21, m22, 0],
[dx, dy, 1]
];
setM(this, m, true);
};
/******** STUBS ********/
contextPrototype.clip = function() {
// TODO: Implement
};
contextPrototype.arcTo = function() {
// TODO: Implement
};
contextPrototype.createPattern = function() {
return new CanvasPattern_;
};
// Gradient / Pattern Stubs
function CanvasGradient_(aType) {
this.type_ = aType;
this.x0_ = 0;
this.y0_ = 0;
this.r0_ = 0;
this.x1_ = 0;
this.y1_ = 0;
this.r1_ = 0;
this.colors_ = [];
}
CanvasGradient_.prototype.addColorStop = function(aOffset, aColor) {
aColor = processStyle(aColor);
this.colors_.push({offset: aOffset,
color: aColor.color,
alpha: aColor.alpha});
};
function CanvasPattern_() {}
// set up externs
G_vmlCanvasManager = G_vmlCanvasManager_;
CanvasRenderingContext2D = CanvasRenderingContext2D_;
CanvasGradient = CanvasGradient_;
CanvasPattern = CanvasPattern_;
})();
} // if
var charset="";
/* This notice must be untouched at all times.
wz_jsgraphics.js v. 2.31
The latest version is available at
http://www.walterzorn.com
or http://www.devira.com
or http://www.walterzorn.de
Copyright (c) 2002-2004 Walter Zorn. All rights reserved.
Created 3. 11. 2002 by Walter Zorn (Web: http://www.walterzorn.com )
Last modified: 28. 3. 2005
Performance optimizations for Internet Explorer
by Thomas Frank and John Holdsworth.
fillPolygon method implemented by Matthieu Haller.
High Performance JavaScript Graphics Library.
Provides methods
- to draw lines, rectangles, ellipses, polygons
with specifiable line thickness,
- to fill rectangles and ellipses
- to draw text.
NOTE: Operations, functions and branching have rather been optimized
to efficiency and speed than to shortness of source code.
LICENSE: LGPL
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License (LGPL) as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA,
or see http://www.gnu.org/copyleft/lesser.html
*/
var jg_ihtm, jg_ie, jg_fast, jg_dom, jg_moz,
jg_n4 = (document.layers && typeof document.classes != "undefined");
function chkDHTM(x, i)
{
x = document.body || null;
jg_ie = x && typeof x.insertAdjacentHTML != "undefined";
jg_dom = (x && !jg_ie &&
typeof x.appendChild != "undefined" &&
typeof document.createRange != "undefined" &&
typeof (i = document.createRange()).setStartBefore != "undefined" &&
typeof i.createContextualFragment != "undefined");
jg_ihtm = !jg_ie && !jg_dom && x && typeof x.innerHTML != "undefined";
jg_fast = jg_ie && document.all && !window.opera;
jg_moz = jg_dom && typeof x.style.MozOpacity != "undefined";
}
function pntDoc()
{
this.wnd.document.write(jg_fast? this.htmRpc() : this.htm);
this.htm = '';
}
function pntCnvDom()
{
var x = document.createRange();
x.setStartBefore(this.cnv);
x = x.createContextualFragment(jg_fast? this.htmRpc() : this.htm);
this.cnv.appendChild(x);
this.htm = '';
}
function pntCnvIe()
{
this.cnv.insertAdjacentHTML("BeforeEnd", jg_fast? this.htmRpc() : this.htm);
this.htm = '';
}
function pntCnvIhtm()
{
this.cnv.innerHTML += this.htm;
this.htm = '';
}
function pntCnv()
{
this.htm = '';
}
function mkDiv(x, y, w, h)
{
this.htm += '<\/div>';
}
function mkDivIe(x, y, w, h)
{
this.htm += '%%'+this.color+';'+x+';'+y+';'+w+';'+h+';';
}
function mkDivPrt(x, y, w, h)
{
this.htm += '
<\/div>';
}
function mkLyr(x, y, w, h)
{
this.htm += '
<\/layer>\n';
}
var regex = /%%([^;]+);([^;]+);([^;]+);([^;]+);([^;]+);/g;
function htmRpc()
{
return this.htm.replace(
regex,
'
\n');
}
function htmPrtRpc()
{
return this.htm.replace(
regex,
'
\n');
}
function mkLin(x1, y1, x2, y2)
{
if (x1 > x2)
{
var _x2 = x2;
var _y2 = y2;
x2 = x1;
y2 = y1;
x1 = _x2;
y1 = _y2;
}
var dx = x2-x1, dy = Math.abs(y2-y1),
x = x1, y = y1,
yIncr = (y1 > y2)? -1 : 1;
if (dx >= dy)
{
var pr = dy<<1,
pru = pr - (dx<<1),
p = pr-dx,
ox = x;
while ((dx--) > 0)
{
++x;
if (p > 0)
{
this.mkDiv(ox, y, x-ox, 1);
y += yIncr;
p += pru;
ox = x;
}
else p += pr;
}
this.mkDiv(ox, y, x2-ox+1, 1);
}
else
{
var pr = dx<<1,
pru = pr - (dy<<1),
p = pr-dy,
oy = y;
if (y2 <= y1)
{
while ((dy--) > 0)
{
if (p > 0)
{
this.mkDiv(x++, y, 1, oy-y+1);
y += yIncr;
p += pru;
oy = y;
}
else
{
y += yIncr;
p += pr;
}
}
this.mkDiv(x2, y2, 1, oy-y2+1);
}
else
{
while ((dy--) > 0)
{
y += yIncr;
if (p > 0)
{
this.mkDiv(x++, oy, 1, y-oy);
p += pru;
oy = y;
}
else p += pr;
}
this.mkDiv(x2, oy, 1, y2-oy+1);
}
}
}
function mkLin2D(x1, y1, x2, y2)
{
if (x1 > x2)
{
var _x2 = x2;
var _y2 = y2;
x2 = x1;
y2 = y1;
x1 = _x2;
y1 = _y2;
}
var dx = x2-x1, dy = Math.abs(y2-y1),
x = x1, y = y1,
yIncr = (y1 > y2)? -1 : 1;
var s = this.stroke;
if (dx >= dy)
{
if (s-3 > 0)
{
var _s = (s*dx*Math.sqrt(1+dy*dy/(dx*dx))-dx-(s>>1)*dy) / dx;
_s = (!(s-4)? Math.ceil(_s) : Math.round(_s)) + 1;
}
else var _s = s;
var ad = Math.ceil(s/2);
var pr = dy<<1,
pru = pr - (dx<<1),
p = pr-dx,
ox = x;
while ((dx--) > 0)
{
++x;
if (p > 0)
{
this.mkDiv(ox, y, x-ox+ad, _s);
y += yIncr;
p += pru;
ox = x;
}
else p += pr;
}
this.mkDiv(ox, y, x2-ox+ad+1, _s);
}
else
{
if (s-3 > 0)
{
var _s = (s*dy*Math.sqrt(1+dx*dx/(dy*dy))-(s>>1)*dx-dy) / dy;
_s = (!(s-4)? Math.ceil(_s) : Math.round(_s)) + 1;
}
else var _s = s;
var ad = Math.round(s/2);
var pr = dx<<1,
pru = pr - (dy<<1),
p = pr-dy,
oy = y;
if (y2 <= y1)
{
++ad;
while ((dy--) > 0)
{
if (p > 0)
{
this.mkDiv(x++, y, _s, oy-y+ad);
y += yIncr;
p += pru;
oy = y;
}
else
{
y += yIncr;
p += pr;
}
}
this.mkDiv(x2, y2, _s, oy-y2+ad);
}
else
{
while ((dy--) > 0)
{
y += yIncr;
if (p > 0)
{
this.mkDiv(x++, oy, _s, y-oy+ad);
p += pru;
oy = y;
}
else p += pr;
}
this.mkDiv(x2, oy, _s, y2-oy+ad+1);
}
}
}
function mkLinDott(x1, y1, x2, y2)
{
if (x1 > x2)
{
var _x2 = x2;
var _y2 = y2;
x2 = x1;
y2 = y1;
x1 = _x2;
y1 = _y2;
}
var dx = x2-x1, dy = Math.abs(y2-y1),
x = x1, y = y1,
yIncr = (y1 > y2)? -1 : 1,
drw = true;
if (dx >= dy)
{
var pr = dy<<1,
pru = pr - (dx<<1),
p = pr-dx;
while ((dx--) > 0)
{
if (drw) this.mkDiv(x, y, 1, 1);
drw = !drw;
if (p > 0)
{
y += yIncr;
p += pru;
}
else p += pr;
++x;
}
if (drw) this.mkDiv(x, y, 1, 1);
}
else
{
var pr = dx<<1,
pru = pr - (dy<<1),
p = pr-dy;
while ((dy--) > 0)
{
if (drw) this.mkDiv(x, y, 1, 1);
drw = !drw;
y += yIncr;
if (p > 0)
{
++x;
p += pru;
}
else p += pr;
}
if (drw) this.mkDiv(x, y, 1, 1);
}
}
function mkOv(left, top, width, height)
{
var a = width>>1, b = height>>1,
wod = width&1, hod = (height&1)+1,
cx = left+a, cy = top+b,
x = 0, y = b,
ox = 0, oy = b,
aa = (a*a)<<1, bb = (b*b)<<1,
st = (aa>>1)*(1-(b<<1)) + bb,
tt = (bb>>1) - aa*((b<<1)-1),
w, h;
while (y > 0)
{
if (st < 0)
{
st += bb*((x<<1)+3);
tt += (bb<<1)*(++x);
}
else if (tt < 0)
{
st += bb*((x<<1)+3) - (aa<<1)*(y-1);
tt += (bb<<1)*(++x) - aa*(((y--)<<1)-3);
w = x-ox;
h = oy-y;
if (w&2 && h&2)
{
this.mkOvQds(cx, cy, -x+2, ox+wod, -oy, oy-1+hod, 1, 1);
this.mkOvQds(cx, cy, -x+1, x-1+wod, -y-1, y+hod, 1, 1);
}
else this.mkOvQds(cx, cy, -x+1, ox+wod, -oy, oy-h+hod, w, h);
ox = x;
oy = y;
}
else
{
tt -= aa*((y<<1)-3);
st -= (aa<<1)*(--y);
}
}
this.mkDiv(cx-a, cy-oy, a-ox+1, (oy<<1)+hod);
this.mkDiv(cx+ox+wod, cy-oy, a-ox+1, (oy<<1)+hod);
}
function mkOv2D(left, top, width, height)
{
var s = this.stroke;
width += s-1;
height += s-1;
var a = width>>1, b = height>>1,
wod = width&1, hod = (height&1)+1,
cx = left+a, cy = top+b,
x = 0, y = b,
aa = (a*a)<<1, bb = (b*b)<<1,
st = (aa>>1)*(1-(b<<1)) + bb,
tt = (bb>>1) - aa*((b<<1)-1);
if (s-4 < 0 && (!(s-2) || width-51 > 0 && height-51 > 0))
{
var ox = 0, oy = b,
w, h,
pxl, pxr, pxt, pxb, pxw;
while (y > 0)
{
if (st < 0)
{
st += bb*((x<<1)+3);
tt += (bb<<1)*(++x);
}
else if (tt < 0)
{
st += bb*((x<<1)+3) - (aa<<1)*(y-1);
tt += (bb<<1)*(++x) - aa*(((y--)<<1)-3);
w = x-ox;
h = oy-y;
if (w-1)
{
pxw = w+1+(s&1);
h = s;
}
else if (h-1)
{
pxw = s;
h += 1+(s&1);
}
else pxw = h = s;
this.mkOvQds(cx, cy, -x+1, ox-pxw+w+wod, -oy, -h+oy+hod, pxw, h);
ox = x;
oy = y;
}
else
{
tt -= aa*((y<<1)-3);
st -= (aa<<1)*(--y);
}
}
this.mkDiv(cx-a, cy-oy, s, (oy<<1)+hod);
this.mkDiv(cx+a+wod-s+1, cy-oy, s, (oy<<1)+hod);
}
else
{
var _a = (width-((s-1)<<1))>>1,
_b = (height-((s-1)<<1))>>1,
_x = 0, _y = _b,
_aa = (_a*_a)<<1, _bb = (_b*_b)<<1,
_st = (_aa>>1)*(1-(_b<<1)) + _bb,
_tt = (_bb>>1) - _aa*((_b<<1)-1),
pxl = new Array(),
pxt = new Array(),
_pxb = new Array();
pxl[0] = 0;
pxt[0] = b;
_pxb[0] = _b-1;
while (y > 0)
{
if (st < 0)
{
st += bb*((x<<1)+3);
tt += (bb<<1)*(++x);
pxl[pxl.length] = x;
pxt[pxt.length] = y;
}
else if (tt < 0)
{
st += bb*((x<<1)+3) - (aa<<1)*(y-1);
tt += (bb<<1)*(++x) - aa*(((y--)<<1)-3);
pxl[pxl.length] = x;
pxt[pxt.length] = y;
}
else
{
tt -= aa*((y<<1)-3);
st -= (aa<<1)*(--y);
}
if (_y > 0)
{
if (_st < 0)
{
_st += _bb*((_x<<1)+3);
_tt += (_bb<<1)*(++_x);
_pxb[_pxb.length] = _y-1;
}
else if (_tt < 0)
{
_st += _bb*((_x<<1)+3) - (_aa<<1)*(_y-1);
_tt += (_bb<<1)*(++_x) - _aa*(((_y--)<<1)-3);
_pxb[_pxb.length] = _y-1;
}
else
{
_tt -= _aa*((_y<<1)-3);
_st -= (_aa<<1)*(--_y);
_pxb[_pxb.length-1]--;
}
}
}
var ox = 0, oy = b,
_oy = _pxb[0],
l = pxl.length,
w, h;
for (var i = 0; i < l; i++)
{
if (typeof _pxb[i] != "undefined")
{
if (_pxb[i] < _oy || pxt[i] < oy)
{
x = pxl[i];
this.mkOvQds(cx, cy, -x+1, ox+wod, -oy, _oy+hod, x-ox, oy-_oy);
ox = x;
oy = pxt[i];
_oy = _pxb[i];
}
}
else
{
x = pxl[i];
this.mkDiv(cx-x+1, cy-oy, 1, (oy<<1)+hod);
this.mkDiv(cx+ox+wod, cy-oy, 1, (oy<<1)+hod);
ox = x;
oy = pxt[i];
}
}
this.mkDiv(cx-a, cy-oy, 1, (oy<<1)+hod);
this.mkDiv(cx+ox+wod, cy-oy, 1, (oy<<1)+hod);
}
}
function mkOvDott(left, top, width, height)
{
var a = width>>1, b = height>>1,
wod = width&1, hod = height&1,
cx = left+a, cy = top+b,
x = 0, y = b,
aa2 = (a*a)<<1, aa4 = aa2<<1, bb = (b*b)<<1,
st = (aa2>>1)*(1-(b<<1)) + bb,
tt = (bb>>1) - aa2*((b<<1)-1),
drw = true;
while (y > 0)
{
if (st < 0)
{
st += bb*((x<<1)+3);
tt += (bb<<1)*(++x);
}
else if (tt < 0)
{
st += bb*((x<<1)+3) - aa4*(y-1);
tt += (bb<<1)*(++x) - aa2*(((y--)<<1)-3);
}
else
{
tt -= aa2*((y<<1)-3);
st -= aa4*(--y);
}
if (drw) this.mkOvQds(cx, cy, -x, x+wod, -y, y+hod, 1, 1);
drw = !drw;
}
}
function mkRect(x, y, w, h)
{
var s = this.stroke;
this.mkDiv(x, y, w, s);
this.mkDiv(x+w, y, s, h);
this.mkDiv(x, y+h, w+s, s);
this.mkDiv(x, y+s, s, h-s);
}
function mkRectDott(x, y, w, h)
{
this.drawLine(x, y, x+w, y);
this.drawLine(x+w, y, x+w, y+h);
this.drawLine(x, y+h, x+w, y+h);
this.drawLine(x, y, x, y+h);
}
function jsgFont()
{
this.PLAIN = 'font-weight:normal;';
this.BOLD = 'font-weight:bold;';
this.ITALIC = 'font-style:italic;';
this.ITALIC_BOLD = this.ITALIC + this.BOLD;
this.BOLD_ITALIC = this.ITALIC_BOLD;
}
var Font = new jsgFont();
function jsgStroke()
{
this.DOTTED = -1;
}
var Stroke = new jsgStroke();
function jsGraphics(id, wnd)
{
this.setColor = new Function('arg', 'this.color = arg.toLowerCase();');
this.setStroke = function(x)
{
this.stroke = x;
if (!(x+1))
{
this.drawLine = mkLinDott;
this.mkOv = mkOvDott;
this.drawRect = mkRectDott;
}
else if (x-1 > 0)
{
this.drawLine = mkLin2D;
this.mkOv = mkOv2D;
this.drawRect = mkRect;
}
else
{
this.drawLine = mkLin;
this.mkOv = mkOv;
this.drawRect = mkRect;
}
};
this.setPrintable = function(arg)
{
this.printable = arg;
if (jg_fast)
{
this.mkDiv = mkDivIe;
this.htmRpc = arg? htmPrtRpc : htmRpc;
}
else this.mkDiv = jg_n4? mkLyr : arg? mkDivPrt : mkDiv;
};
this.setFont = function(fam, sz, sty)
{
this.ftFam = fam;
this.ftSz = sz;
this.ftSty = sty || Font.PLAIN;
};
this.drawPolyline = this.drawPolyLine = function(x, y, s)
{
for (var i=0 ; i>1, b = (h -= 1)>>1,
wod = (w&1)+1, hod = (h&1)+1,
cx = left+a, cy = top+b,
x = 0, y = b,
ox = 0, oy = b,
aa2 = (a*a)<<1, aa4 = aa2<<1, bb = (b*b)<<1,
st = (aa2>>1)*(1-(b<<1)) + bb,
tt = (bb>>1) - aa2*((b<<1)-1),
pxl, dw, dh;
if (w+1) while (y > 0)
{
if (st < 0)
{
st += bb*((x<<1)+3);
tt += (bb<<1)*(++x);
}
else if (tt < 0)
{
st += bb*((x<<1)+3) - aa4*(y-1);
pxl = cx-x;
dw = (x<<1)+wod;
tt += (bb<<1)*(++x) - aa2*(((y--)<<1)-3);
dh = oy-y;
this.mkDiv(pxl, cy-oy, dw, dh);
this.mkDiv(pxl, cy+oy-dh+hod, dw, dh);
ox = x;
oy = y;
}
else
{
tt -= aa2*((y<<1)-3);
st -= aa4*(--y);
}
}
this.mkDiv(cx-a, cy-oy, w+1, (oy<<1)+hod);
};
/* fillPolygon method, implemented by Matthieu Haller.
This javascript function is an adaptation of the gdImageFilledPolygon for Walter Zorn lib.
C source of GD 1.8.4 found at http://www.boutell.com/gd/
THANKS to Kirsten Schulz for the polygon fixes!
The intersection finding technique of this code could be improved
by remembering the previous intertersection, and by using the slope.
That could help to adjust intersections to produce a nice
interior_extrema. */
this.fillPolygon = function(array_x, array_y)
{
var i;
var y;
var miny, maxy;
var x1, y1;
var x2, y2;
var ind1, ind2;
var ints;
var n = array_x.length;
if (!n) return;
miny = array_y[0];
maxy = array_y[0];
for (i = 1; i < n; i++)
{
if (array_y[i] < miny)
miny = array_y[i];
if (array_y[i] > maxy)
maxy = array_y[i];
}
for (y = miny; y <= maxy; y++)
{
var polyInts = new Array();
ints = 0;
for (i = 0; i < n; i++)
{
if (!i)
{
ind1 = n-1;
ind2 = 0;
}
else
{
ind1 = i-1;
ind2 = i;
}
y1 = array_y[ind1];
y2 = array_y[ind2];
if (y1 < y2)
{
x1 = array_x[ind1];
x2 = array_x[ind2];
}
else if (y1 > y2)
{
y2 = array_y[ind1];
y1 = array_y[ind2];
x2 = array_x[ind1];
x1 = array_x[ind2];
}
else continue;
// modified 11. 2. 2004 Walter Zorn
if ((y >= y1) && (y < y2))
polyInts[ints++] = Math.round((y-y1) * (x2-x1) / (y2-y1) + x1);
else if ((y == maxy) && (y > y1) && (y <= y2))
polyInts[ints++] = Math.round((y-y1) * (x2-x1) / (y2-y1) + x1);
}
polyInts.sort(integer_compare);
for (i = 0; i < ints; i+=2)
this.mkDiv(polyInts[i], y, polyInts[i+1]-polyInts[i]+1, 1);
}
};
this.drawString = function(txt, x, y)
{
this.htm += ''+
txt +
'<\/div>';
};
/* drawStringRect() added by Rick Blommers.
Allows to specify the size of the text rectangle and to align the
text both horizontally (e.g. right) and vertically within that rectangle */
this.drawStringRect = function(txt, x, y, width, halign)
{
this.htm += '
'+
txt +
'<\/div>';
};
this.drawImage = function(imgSrc, x, y, w, h)
{
this.htm += '
'+
'
'+
'<\/div>';
};
this.clear = function()
{
this.htm = "";
if (this.cnv) this.cnv.innerHTML = this.defhtm;
};
this.mkOvQds = function(cx, cy, xl, xr, yt, yb, w, h)
{
this.mkDiv(xr+cx, yt+cy, w, h);
this.mkDiv(xr+cx, yb+cy, w, h);
this.mkDiv(xl+cx, yb+cy, w, h);
this.mkDiv(xl+cx, yt+cy, w, h);
};
this.setStroke(1);
this.setFont('verdana,geneva,helvetica,sans-serif', String.fromCharCode(0x31, 0x32, 0x70, 0x78), Font.PLAIN);
this.color = '#000000';
this.htm = '';
this.wnd = wnd || window;
if (!(jg_ie || jg_dom || jg_ihtm)) chkDHTM();
if (typeof id != 'string' || !id) this.paint = pntDoc;
else
{
this.cnv = document.all? (this.wnd.document.all[id] || null)
: document.getElementById? (this.wnd.document.getElementById(id) || null)
: null;
this.defhtm = (this.cnv && this.cnv.innerHTML)? this.cnv.innerHTML : '';
this.paint = jg_dom? pntCnvDom : jg_ie? pntCnvIe : jg_ihtm? pntCnvIhtm : pntCnv;
}
this.setPrintable(false);
}
function integer_compare(x,y)
{
return (x < y) ? -1 : ((x > y)*1);
}
var charset="";
/******************************************************************************
* kaXmlOverlay - XML server side generated overlay for kaMap.
*
* Piergiorgio Navone
*
* $Id: kaXmlOverlay.js,v 1.4 2006/08/08 13:17:55 pspencer Exp $
*****************************************************************************/
/******************************************************************************
* BEGIN section in Wiki syntax
=kaXmlOverlay Quick HOW-TO=
* '''1''' Import scripts in your page:
* '''2''' Let ka-Map initialize itself: the next steps should wait at lest the KAMAP_MAP_INITIALIZED event.
* '''3''' Create a kaXmlOverlay object:
myXmlOverlay = new kaXmlOverlay( ICTMAP, 250 );
* '''4''' Add some objects on the overlay layer. There are two ways to do that
** Call the loadXml method: this method load an XML document from the web server.
myXmlOverlay.loadXml('points.xml');
** Write a JavaScript function to add your objects:
var my_point = myXmlOverlay.addNewPoint('Point ID', longuitude, latitude);
var my_symbol = new kaXmlSymbol();
my_symbol.size = 12;
my_symbol.color = '#ff0000';
my_point.addGraphic(my_symbol);
* '''5''' To have a periodic update:
myInterval = setInterval("myMovingOverlay.loadXml('xmlget.phtml')",5000);
--------------------------------------------
= kaXmlOverlay Reference=
This document describe the interface of the JavaScript kaXmlOverlay library as well as the XLM documents describing overlays. The document is divided in tree sections:
# A summary of JavaScript objects and functions
# The definition of the XML
# An in deep description of attributes common to both XML and JavaScript functions
== JavaScript API==
In this section there is a list of main classes with methods an properties that you ca use to programmatically add overlays to your map.
A detailed an updated documentation for each function is maintained as JavaDoc like comments in the source code.
=== Class kaXmlOverlay===
This class represent a map layer where is possible to add overlays.
To instantiate this class use the constructor
kaXmlOverlay( oKaMap, xml_url )
;oKaMap: A kaMap object
;zIndex: The z index of the layer
To load an XML document with overlay description call the method
kaXmlOverlay.prototype.loadXml = function(xml_url)
;xml_url: URL of th XML with points to plot
To add a new point to an overlay
kaXmlOverlay.prototype.addNewPoint = function(pid, x, y)
;pid: Point ID
;x: X geo-coordinate
;y: Y geo-coordinate
;return: A kaXmlPoint object with the given point ID.
To retrieve an existing point from an overlay call
kaXmlOverlay.prototype.getPointObject = function(pid)
;pid: Point ID
;return: The kaXmlPoint object given the point ID. null if not found.
To remove one or more points from the overlay
kaXmlOverlay.prototype.removePoint = function( pid )
;pid: Point ID or a regexp. If pid is null or not present remove all points.
=== Class kaXmlPoint===
A kaXmlPoint represents a group of graphic object on the overlay layer. The point is placed on the map at specified geographic coordinates. A point can be moved on the map without the need of redrawing all its graphic objects.
To instantiate a new point don't use the constructor but call the ''kaXmlOverlay.addNewPoint()'' function.
To place or move a kaXmlPoint on the map call
kaXmlPoint.prototype.setPosition = function( x, y )
;x: X geo-coordinate
;y: Y geo-coordinate
To clear all graphics associated with the point call the method
kaXmlPoint.prototype.clear = function()
To add graphic objects to a point use the method
kaXmlPoint.prototype.addGraphic = function( obj )
;obj: an object of type kaXmlSymbol, kaXmlIcon, kaXmlLabel, kaXmlLinestring or kaXmlPolygon
To manually set the HTML content of a kaXmlPoint use the method
kaXmlPoint.prototype.setInnerHtml = function(ihtml)
;ihtml: A string containing the HTML
This function delete any other content of the point.
=== Graphic objects classes===
The graphic objects that can be displayed are:
* kaXmlSymbol
* kaXmlLabel
* kaXmlIcon
* kaXmlLinestring
* kaXmlPolygon
All this classes have a constructor without parameters and different attributes: the attributes are described in the following of the document.
To use one of these objects create a new instance, configure it setting its properties ad add it to a ''kaXmlPoint'' with the method ''addGraphic''.
'''Using CANVAS for vector graphics'''
Symbols, linestrings and polygons are drawn using
. To change this behaviour and use
the previous implementation (drawgeom.phtml and wz_jsgraphcs) use
xmlOverlayUseCanvas = false;
== XML Document Type Definition==
----------
----------
=== XML document example===
just a label
== Overlay objects attributes==
=== POINT ()===
The POINT is the father of all objects you can display on the overlay layer.
Wherever you want dislay someting on the overlay layer you have to define a
POINT than add to the POINT icons, symbols, labels, etc.
'''POINT attributes:'''
;id: (string, mandatory) This string is used to identify the point. It's needed to translate, delete, redraw the POINT.
;x: (number, required) The X coordinate in map units.
;y: (number, required) The Y coordinate in map units.
=== SYMBOL (kaXmlSymbol, )===
A symbol is a graphic element drawn at POINT coordinates. It's similar to an icon, but it has a parametric color and size.
'''SYMBOL attributes:'''
;shape: (string, optional) The shape of the symbol. Today implementation allows only the shapes ''bullet'' and ''square''.
;color: (string, optional) The fill color of the symbol (HTML syntax).
;bcolor: (string, optional) Border color (HTML syntax).
;size: (integer, optional) The size in pixels of the symbol.
;stroke: (integer, optional) Line width in pixels.
;opacity: (number, optional) 1.0 is opaque, 0.0 is fully transparent.
=== ICON (kaXmlIcon, )===
An icon drawn at POINT coordinates. The image is defined with an URL. Width and height of the image must be provided, because the icon will be centred at POINT coordinates.
'''ICON attributes'''
;src: (string, required) The relative or absolute URL of the image
;w: (integer, required) Width of the image in pixels
;h: (integer, required) Height of the image in pixels
;px: (integer, optional) Horizontal offset in pixels (positive to move the icon on the right).
;py: (integer, optional) Vertical offset in pixels (negative to rise the icon).
;opacity: (number, optional) 1.0 is opaque, 0.0 is fully transparent.
=== LABEL (kaXmlLabel, )===
A text label is written near the POINT. POINT coordinates represent the top-left corner of the LABEL.
'''LABEL attributes'''
;color: (string, optional) Text color (HTML syntax).
;boxcolor: (string, optional) Background color behind the text (HTML syntax).
;w: (integer, optional) Width of the label in pixels.
;h: (integer, optional) Height of the label in pixels.
;px: (integer, optional) Horizontal offset in pixels (positive to move the label on the right).
;py: (integer, optional) Vertical offset in pixels (negative to rise the label).
;font: (string, optional) The text font (HTML syntax).
;fsize: (string, optional) Font size (HTML syntax).
;text: (string, required) The label text: this attribute is present only in JavaScript: in the XML syntax the text is the content of the element.
=== LINESTRING (kaXmlLinestring, )===
This element represent a geographic feature, a single line in geographic coordinates that will be scaled with the map.
The coordinates of the line must be expressed a string in the form
x0 y0, x1 y1, [...], xn yn
The coordinates string is the text node of the XML element. In JavaScript the coordinates string is passed
to the object with the method readCoordinates().
'''LINESTRING attributes'''
;color: (string, optional) Line color (HTML syntax).
;stroke: (integer, optional) Line width in pixels.
;opacity: (number, optional) 1.0 is opaque, 0.0 is fully transparent.
=== POLYGON (kaXmlPolygon, )===
This element represent a geographic feature, a single polygon in geographic coordinates that will be scaled with the map.
'''POLYGON attributes'''
;color: (string, optional) Surface color (HTML syntax).
;bcolor: (string, optional) Border color (HTML syntax).
;stroke: (integer, optional) Border width in pixels.
;opacity: (number, optional) 1.0 is opaque, 0.0 is fully transparent.
---------------------------------------------------
= FAQs=
''Error: xmlDocument has no properties''
;: The XML is served with a wrong mime type by your web server. It should have a mime type "text/xml". Configure your server to associate ".xml" files with the correct mime, or, if you generate the XML dynamically, use a directive to set the mime type.
''In IE6 with excanvas.js canvas are not displayed''
;: The HTML page must begin with
---------------------------------------------------
= TODOs=
* Evaluate the use of custom onclick or ondblclick events on points
* Add a tooltip for overlay points
* Make the label management smarter
* END section in Wiki syntax
*****************************************************************************/
/**
* kaXmlOverlay( oKaMap, xml_url )
*
* oKaMap A kaMap object
* zIndex The z index of the layer
*/
function kaXmlOverlay( oKaMap, zIndex )
{
kaTool.apply( this, [oKaMap] );
this.name = 'kaXmlOverlay';
for (var p in kaTool.prototype)
{
if (!kaXmlOverlay.prototype[p])
kaXmlOverlay.prototype[p]= kaTool.prototype[p];
}
this.urlBase = null;
//this.urlBase = this.kaMap.server;
//this.urlBase += (this.urlBase!=''&&this.urlBase.substring(-1)!='/')?'':'/';
// The list of overlay points
this.ovrObjects = new Array();
// The cavas of the overlay layer
this.z_index = zIndex;
this.overlayCanvas = this.kaMap.createDrawingCanvas( zIndex );
// Register for events
this.kaMap.registerForEvent( KAMAP_SCALE_CHANGED, this, this.scaleChanged );
}
kaXmlOverlay.prototype.scaleChanged = function( eventID, mapName ) {
if (this.ovrObjects == null) return;
for (var i=0; i < this.ovrObjects.length; i++) {
if (this.ovrObjects[i]) this.ovrObjects[i].rescale();
}
};
/**
* Remove the overlay layer and free resources user by overlay objects.
*/
kaXmlOverlay.prototype.remove = function() {
this.kaMap.deregisterForEvent( KAMAP_SCALE_CHANGED, this, this.scaleChanged );
this.removePoint();
this.kaMap.removeDrawingCanvas(this.overlayCanvas);
};
/**
* Load XML from the server and update the overlay.
*
* xml_url URL of th XML with points to plot
*/
kaXmlOverlay.prototype.loadXml = function(xml_url) {
// The URL of the XML
this.xmlOvrUrl = this.urlNormalize(xml_url);
call(this.xmlOvrUrl,this,this.loadXmlCallback);
};
/**
* initializeの後にurlBaseにURLをセットしておく
*/
kaXmlOverlay.prototype.setBaseUrl = function(){
this.urlBase = this.kaMap.server;
this.urlBase += (this.urlBase!=''&&this.urlBase.substring(-1)!='/')?'':'/';
}
//API化によるクロスドメイン対応(JSON化)
kaXmlOverlay.prototype.loadXml2 = function(xml_url) {
// The URL of the XML
this.setBaseUrl();
this.xmlOvrUrl = this.urlNormalize(xml_url);
var oJsr = new JSONscriptRequest(this.xmlOvrUrl+'&callback=jsonPointCallback');
oJsr.buildScriptTag();
oJsr.addScriptTag();
};
function jsonPointCallback(data){
if(typeof(oJsr) != "undefined") oJsr.removeScriptTag();
ICTMAP.myXmlOverlay.loadXmlDoc2(data);
}
/**
* Defines the DOMParser object for IE
*/
if (typeof DOMParser == "undefined") {
DOMParser = function () {};
DOMParser.prototype.parseFromString = function (str, contentType) {
if (typeof ActiveXObject != "undefined") {
var d = new ActiveXObject("MSXML.DomDocument");
d.loadXML(str);
return d;
} else if (typeof XMLHttpRequest != "undefined") {
var req = new XMLHttpRequest;
req.open("GET", "data:" + (contentType || "application/xml") +
";charset=utf-8," + encodeURIComponent(str), false);
if (req.overrideMimeType) {
req.overrideMimeType(contentType);
}
req.send(null);
return req.responseXML;
}
};
}
kaXmlOverlay.prototype.loadXmlCallback = function(xml_string) {
var xmlDocument = (new DOMParser()).parseFromString(xml_string, "text/xml");
this.loadXmlDoc(xmlDocument);
};
kaXmlOverlay.prototype.loadXmlDoc = function(xmlDocument) {
//alert("loadXmlDoc");
var objDomTree = xmlDocument.documentElement;
var dels = objDomTree.getElementsByTagName("delete");
for (var i=0; i 0; ) {
if (this.ovrObjects[i] != null) {
this.ovrObjects[i].removeFromMap();
delete this.ovrObjects[i];
this.ovrObjects[i] = null;
}
this.ovrObjects.splice(i,1);
}
//this.ovrObjects = new Array(); // sakai
} else if(this.removePoint.arguments.length == 2){ // sakai
var re = new RegExp("^"+idtype);
for (var i=this.ovrObjects.length; i-- > 0; ) {
if (this.ovrObjects[i] != null) {
if (re.test(this.ovrObjects[i].pid)) {
this.ovrObjects[i].removeFromMap();
delete this.ovrObjects[i];
this.ovrObjects[i] = null;
this.ovrObjects.splice(i,1);
}
} else {
this.ovrObjects.splice(i,1);
}
}
} else {
//var re = new RegExp(pid);
for (var i=this.ovrObjects.length; i-- > 0; ) {
if (this.ovrObjects[i] != null) {
//if (re.test(this.ovrObjects[i].pid)) {
if (re == pid){
this.ovrObjects[i].removeFromMap();
delete this.ovrObjects[i];
this.ovrObjects[i] = null;
this.ovrObjects.splice(i,1);
}
} else {
this.ovrObjects.splice(i,1);
}
}
}
};
/**
* Base class for all graphics elements.
*/
function kaXmlGraphicElement() {}
/**
* Initialize the graphics element from an XML element
*
* point The parent kaXmlPoint object
* domElement The XML DOM element that describe the graphic
*/
kaXmlGraphicElement.prototype.parseElement = function(point, domElement) {};
/**
* Draw the graphics element
*
* point The parent kaXmlPoint object
*/
kaXmlGraphicElement.prototype.draw = function(point) {};
/**
* Draw the graphics element
*
* point The parent kaXmlPoint object
*/
kaXmlGraphicElement.prototype.rescale = function(point) {};
/**
* Dispose the resources allocated in the graphics element
*
* point The parent kaXmlPoint object
*/
kaXmlGraphicElement.prototype.remove = function(point) {};
/**
* Construct a symbol
*/
function kaXmlSymbol() {
kaXmlGraphicElement.apply(this);
if (_BrowserIdent_hasCanvasSupport())
kaXmlSymbol.prototype['draw'] = kaXmlSymbol.prototype['draw_canvas'];
else
kaXmlSymbol.prototype['draw'] = kaXmlSymbol.prototype['draw_js'];
for (var p in kaXmlGraphicElement.prototype) {
if (!kaXmlSymbol.prototype[p])
kaXmlSymbol.prototype[p]= kaXmlGraphicElement.prototype[p];
}
this.shape = "bullet";
this.size = 10;
this.stroke = 1;
this.color = null;
this.bcolor = null;
this.opacity = 1;
this.canvas = null;
this.ldiv = null;
}
kaXmlSymbol.prototype.remove = function(point) {
this.canvas = null;
this.ldiv = null;
};
kaXmlSymbol.prototype.parseElement = function(point, domElement) {
this.shape = domElement.getAttribute("shape");
this.size = parseInt(domElement.getAttribute("size"));
var c = domElement.getAttribute("color");
if (c != null) this.color = c;
var c = domElement.getAttribute("bcolor");
if (c != null) this.bcolor = c;
c = parseFloat(domElement.getAttribute("opacity"));
if(! isNaN(c)) this.opacity = c;
c = parseInt(domElement.getAttribute("stroke"));
if (! isNaN(c)) this.stroke = c;
};
kaXmlSymbol.prototype.draw_js = function(point) {
var jsgObject = new jsGraphics(point.divId);
var d = this.size / 2;
jsgObject.setStroke(this.stroke);
if (this.shape == 'square') {
if (this.color) {
jsgObject.setColor(this.color);
jsgObject.fillRect(-d, -d, this.size, this.size);
}
if (this.bcolor) {
jsgObject.setColor(this.bcolor);
jsgObject.fillRect(-d, -d, this.size, this.size);
}
} else {
if (this.color) {
jsgObject.setColor(this.color);
jsgObject.fillEllipse(-d, -d, this.size, this.size);
}
if (this.bcolor) {
jsgObject.setColor(this.bcolor);
jsgObject.drawEllipse(-d, -d, this.size, this.size);
}
}
jsgObject.paint();
};
kaXmlSymbol.prototype.draw_canvas = function(point) {
var d = Math.floor((this.size + this.stroke) / 2);
if (this.canvas == null) {
this.ldiv = document.createElement( 'div' );
this.ldiv.style.position = 'absolute';
this.ldiv.style.left = -d+'px';
this.ldiv.style.top = -d+'px';
point.div.appendChild(this.ldiv);
this.canvas = _BrowserIdent_newCanvas(this.ldiv);
_BrowserIdent_setCanvasHW(this.canvas,d*2,d*2);
}
var ctx = _BrowserIdent_getCanvasContext(this.canvas);
ctx.save();
//alert("Point("+point.pid+") Size("+this.size+") D("+d+")");
ctx.translate(d,d);
ctx.globalAlpha = this.opacity;
ctx.lineWidth = this.stroke;
if (this.bcolor) ctx.strokeStyle = this.bcolor;
if (this.color) ctx.fillStyle = this.color;
if (this.shape == 'square') {
if (this.color) ctx.fillRect(-this.size/2.0,-this.size/2.0,this.size,this.size);
if (this.bcolor) ctx.strokeRect(-this.size/2.0,-this.size/2.0,this.size,this.size);
} else {
ctx.beginPath();
ctx.arc(0,0,this.size/2.0,0,Math.PI*2,false);
if (this.color) ctx.fill();
if (this.bcolor) ctx.stroke();
}
ctx.restore();
};
/**
* Construct a geographic feature
*/
function kaXmlFeature( point ) {
kaXmlGraphicElement.apply(this);
for (var p in kaXmlGraphicElement.prototype) {
if (!kaXmlFeature.prototype[p])
kaXmlFeature.prototype[p]= kaXmlGraphicElement.prototype[p];
}
this.stroke = 1;
this.color = null;
this.bcolor = null;
this.opacity = 1;
this.cxmin = 0;
this.cymax = 0;
this.cymin = 0;
this.cxmax = 0;
this.coords = "";
this.img = null;
this.canvas = null;
this.ldiv = null;
this.xn = null;
this.yn = null;
// Calculate the min cellSize
var map = point.xml_overlay.kaMap.getCurrentMap();
var scales = map.getScales();
this.maxScale = scales[scales.length - 1];
this.mcs = point.xml_overlay.kaMap.cellSize / (point.xml_overlay.kaMap.getCurrentScale() / this.maxScale);
}
kaXmlFeature.prototype.remove = function(point) {
this.img = null;
this.canvas = null;
this.ldiv = null;
this.coords = null;
this.xn.splice(0);
this.yn.splice(0);
};
kaXmlFeature.prototype.parseElement = function(point, domElement) {
var t;
t = parseInt(domElement.getAttribute("stroke"));
if (! isNaN(t)) this.stroke = t;
t = domElement.getAttribute("color");
if (t != null) this.color = t;
t = domElement.getAttribute("bcolor");
if (t != null) this.bcolor = t;
t = parseFloat(domElement.getAttribute("opacity"));
if(! isNaN(t)) this.opacity = t;
var text = "";
if (domElement.firstChild != null) {
text = domElement.firstChild.data;
this.readCoordinates(point, text);
}
};
/**
* Read the feature coordinates from a string
*
* x0 y0, x1 y1, [...], xn yn
*/
kaXmlFeature.prototype.readCoordinates = function(point, text) {
var cx = new Array();
var cy = new Array();
var pp = text.split(',');
var i;
for (i=0; ithis.cymax) this.cymax = y;
if (i==0 || ythis.cxmax) this.cxmax = x;
}
this.xn = new Array();
this.yn = new Array();
// Normalize the coordinates
for (i=0; i0) this.coords += ",";
this.coords += Math.round(x)+","+Math.round(y);
this.xn.push(x);
this.yn.push(y);
}
};
kaXmlFeature.prototype.rescale = function(point) {
this.draw(point);
};
/**
* Construct a linestring
*/
function kaXmlLinestring( point ) {
kaXmlFeature.apply(this, [point]);
if (_BrowserIdent_hasCanvasSupport())
kaXmlLinestring.prototype['draw'] = kaXmlLinestring.prototype['draw_canvas'];
else
kaXmlLinestring.prototype['draw'] = kaXmlLinestring.prototype['draw_server'];
for (var p in kaXmlFeature.prototype) {
if (!kaXmlLinestring.prototype[p])
kaXmlLinestring.prototype[p]= kaXmlFeature.prototype[p];
}
}
kaXmlLinestring.prototype.draw_server = function(point) {
var xy = point.xml_overlay.kaMap.geoToPix( this.cxmin, this.cymax );
var x0 = xy[0];
var y0 = xy[1];
xy = point.xml_overlay.kaMap.geoToPix( point.div.lon, point.div.lat );
var xr = xy[0];
var yr = xy[1];
var border = 5;
if (this.img == null) {
this.img = document.createElement( 'img' );
point.div.appendChild( this.img );
this.img.style.position = 'absolute';
}
this.img.style.top = (y0 - yr - border)+'px';
this.img.style.left = (x0 - xr - border)+'px';
var scf = point.xml_overlay.kaMap.getCurrentScale() / this.maxScale;
var it = _BrowserIdent_getPreferredImageType();
var u = point.xml_overlay.kaMap.server+"/XMLOverlay/drawgeom.phtml?gt=L&st="+this.stroke+"&bp="+border+"&sc="+scf+"&cl="+this.coords;
if (this.color != null) u += "&lc="+escape(this.color);
if (it == "P") {
u += "&it=P";
} else {
u += "&it=G";
}
if (_BrowserIdent_getPreferredOpacity() == "server") {
if (this.opacity < 1) u += "&op="+(this.opacity*100);
} else {
if (this.opacity < 1) _BrowserIdent_setOpacity(this.img, this.opacity);
}
this.img.src = u;
};
kaXmlLinestring.prototype.draw_canvas = function(point) {
var xy = point.xml_overlay.kaMap.geoToPix( this.cxmin, this.cymax );
var x0 = xy[0];
var y0 = xy[1];
xy = point.xml_overlay.kaMap.geoToPix( this.cxmax, this.cymin );
var x1 = xy[0];
var y1 = xy[1];
xy = point.xml_overlay.kaMap.geoToPix( point.div.lon, point.div.lat );
var xr = xy[0];
var yr = xy[1];
var border = 5;
var scf = point.xml_overlay.kaMap.getCurrentScale() / this.maxScale;
var sizex = (x1 - x0) + (border*2);
var sizey = (y1 - y0) + (border*2);
if (this.canvas == null) {
this.ldiv = document.createElement( 'div' );
this.ldiv.style.position = 'absolute';
point.div.appendChild(this.ldiv);
this.canvas = _BrowserIdent_newCanvas(this.ldiv);
}
this.ldiv.style.left = (x0 - xr - border)+'px';
this.ldiv.style.top = (y0 - yr - border)+'px';
_BrowserIdent_setCanvasHW(this.canvas,sizey,sizex);
var ctx = _BrowserIdent_getCanvasContext(this.canvas);
ctx.save();
ctx.clearRect(0, 0, sizex, sizey);
ctx.translate(border,border);
ctx.strokeStyle = this.color;
ctx.globalAlpha = this.opacity;
ctx.lineWidth = this.stroke;
ctx.beginPath();
ctx.moveTo(this.xn[0]/scf, this.yn[0]/scf);
var i;
for (i=1; i0) this.ldiv.style.width = this.w+'px';
else this.ldiv.style.whiteSpace = 'nowrap';
if (this.h>0) this.ldiv.style.height = this.h+'px';
this.ltxt = document.createTextNode(this.text);
this.ldiv.appendChild( this.ltxt );
point.div.appendChild( this.ldiv );
};
/**
* Construct an icon
*/
function kaXmlIcon() {
kaXmlGraphicElement.apply(this);
if (_BrowserIdent_hasCanvasSupport())
//kaXmlIcon.prototype['draw'] = kaXmlIcon.prototype['draw_canvas']; // アイコンの描画をdraw_plainに統一 sakai
kaXmlIcon.prototype['draw'] = kaXmlIcon.prototype['draw_plain'];
else
kaXmlIcon.prototype['draw'] = kaXmlIcon.prototype['draw_plain'];
for (var p in kaXmlGraphicElement.prototype) {
if (!kaXmlIcon.prototype[p])
kaXmlIcon.prototype[p]= kaXmlGraphicElement.prototype[p];
}
this.icon_src = null;
this.icon_w = 0;
this.icon_h = 0;
this.xoff = 0;
this.yoff = 0;
this.rot = 0;
this.ldiv = null;
this.img = null;
this.canvas = null;
}
kaXmlIcon.prototype.remove = function(point) {
this.ldiv = null;
this.canvas = null;
if (this.img) this.img.onload = null;
this.img = null;
};
kaXmlIcon.prototype.parseElement = function(point, domElement) {
this.icon_src = point.xml_overlay.urlNormalize(domElement.getAttribute("src"));
this.icon_w = parseInt(domElement.getAttribute("w"));
this.icon_h = parseInt(domElement.getAttribute("h"));
var t;
t = parseInt(domElement.getAttribute("px"));
if (!isNaN(t)) {
this.xoff = t;
}
t = parseInt(domElement.getAttribute("py"));
if (!isNaN(t)) {
this.yoff = t;
}
t = parseInt(domElement.getAttribute("rot"));
if (!isNaN(t)) {
this.rot = t;
}
};
kaXmlIcon.prototype.parseElement2 = function(point, data) {
this.icon_src = point.xml_overlay.urlNormalize(data.src);
this.icon_w = parseInt(data.w);
this.icon_h = parseInt(data.h);
var t;
t = parseInt(data.px);
if (!isNaN(t)) {
this.xoff = t;
}
t = parseInt(data.py);
if (!isNaN(t)) {
this.yoff = t;
}
t = parseInt(data.rot);
if (!isNaN(t)) {
this.rot = t;
}
};
kaXmlIcon.prototype.draw_canvas = function(point) {
var dx = -this.icon_w / 2 + this.xoff;
var dy = -this.icon_h / 2 + this.yoff;
if (this.canvas == null) {
this.ldiv = document.createElement( 'div' );
this.ldiv.style.position = 'absolute';
this.ldiv.style.top = dy+'px';
this.ldiv.style.left = dx+'px';
this.ldiv.style.zIndex = 400;
point.div.appendChild(this.ldiv);
this.canvas = _BrowserIdent_newCanvas(this.ldiv);
_BrowserIdent_setCanvasHW(this.canvas,this.icon_h*2,this.icon_w*2);
}
var ctx = _BrowserIdent_getCanvasContext(this.canvas);
ctx.save();
ctx.translate(-dx,-dy);
ctx.rotate(this.rot * Math.PI/180);
this.img = new Image();
this.img.src = this.icon_src;
var timg = this.img;
var tw = this.icon_w;
var th = this.icon_h;
//this.img.onload = function() { // IEだと1度読み込むと2度目のonloadが起きないコメントアウト sakai
//alert("icon img onload");
ctx.drawImage(timg, dx, dy, tw, th);
ctx.restore();
//}
};
kaXmlIcon.prototype.draw_plain = function(point) {
var dx = -this.icon_w / 2 + this.xoff;
var dy = -this.icon_h / 2 + this.yoff;
this.ldiv = document.createElement( 'div' );
this.ldiv.style.position = 'absolute';
this.ldiv.style.top = dy+'px';
this.ldiv.style.left = dx+'px';
this.img = document.createElement( 'img' );
this.img.src = this.icon_src;
//img.class = 'png24';
this.img.width = this.icon_w;
this.img.height = this.icon_h;
// sakai
if(point.pointtype == "KIHON"){ // 標準ポイント
this.ldiv.onmouseover = function(){
var tmp = getRawObject("kihonlabel");
var x = point.div.offsetLeft;
var y = point.div.offsetTop;
tmp.style.top = y + "px";
tmp.style.left = (x+12) + "px";
tmp.style.display = 'inline';
tmp.innerHTML = getRawObject("label_"+point.divId).innerHTML;
point.div.canvas.appendChild(tmp);
};
this.ldiv.onmouseout = function(){
var tmp = getRawObject("kihonlabel");
tmp.style.display = 'none';
//getRawObject("label_"+point.divId).style.display = "none";
};
this.img.style.cursor = 'pointer';
this.ldiv.style.zIndex=251;
this.img.style.zIndex=252;
this.img.style.position="absolute";
}else if(point.onclickflg){ // ユーザポイント
this.ldiv.onmouseover = function(res,flg){
if(flg != 1){
getRawObject('namelist').style.display = 'none';
}
//point.div.style.zoom = 1.8;
var num = point.pid.substr(1);
if(flg != 1){
searchSamePoint(point.div);
}
};
ICTMAP.iconMouseOver[point.sid] = this.ldiv.onmouseover;
this.ldiv.onmouseout = function(){
point.div.style.zoom = 1;
var num = point.pid.substr(1);
//getRawObject("datalist"+num).style.borderBottom = "dotted 1px #072F49";
};
ICTMAP.iconMouseOut[point.sid] = this.ldiv.onmouseout;
this.ldiv.onclick = function(){
//clearOverlaysymbolhtml();
//clickIconEvent(point);
if(typeof(point.opts.onclick) == "function"){
point.opts.onclick(point.pid);
}else if(point.opts.infoWindowHtml != null && point.opts.infoWindowHtml != ""){
clickIconEvent(point,point.opts.infoWindowHtml);
}else if(point.opts.infoWindowUrl != null && point.opts.infoWindowUrl != ""){
clickIconEvent(point,"",point.opts.infoWindowUrl);
}else if(point.opts.infoIframeWindowSrc != null && point.opts.infoIframeWindowSrc != ""){
clickIconEvent(point,"","",point.opts.infoIframeWindowSrc,point.opts.infoIframeWidth,point.opts.infoIframeHeight);
}
};
ICTMAP.iconClick[point.sid] = this.ldiv.onclick;
ICTMAP.IctMap.arrOnclick[ICTMAP.IctMap.arrOnclickIndex] = this.ldiv.onclick;
ICTMAP.IctMap.arrOnclickIndex++;
this.img.style.cursor = 'pointer';
this.ldiv.style.zIndex=501;
this.img.style.zIndex=502;
this.img.style.position="absolute";
}
this.ldiv.appendChild( this.img );
point.div.appendChild( this.ldiv );
};
/**
* アイコンにマウスが乗ったときに同じポイントに登録アイコンがないか調べる
*/
function searchSamePoint(aobj){
var x = aobj.style.left;
var y = aobj.style.top;
var tmpid = aobj.id;
var len = ICTMAP.aObjects.length;
var dst = [];
for (var i=0; i 0){
//var dst = aobj.sid;
for(i=0;i 0){
var objText = document.createTextNode(point.pointName);
obj.appendChild(objText);
return obj;
}else{
return null;
}
}
/**
* アイコンクリック時に呼び出されるイベント sakai
*/
function clickIconEvent(point,html,url,iframeSrc,iframeWidth,iframeHeight){
getRawObject('namelist').style.display='none';
var tmp = getRawObject("pointinfo");
var x = point.div.offsetTop;
var y = point.div.offsetLeft;
tmp.style.top = x + "px";
tmp.style.left = (y - 50) + "px";
tmp.style.visibility = 'visible';
tmp.style.display = 'block';
tmp.onmouseover = function(){
myKaRubberZoom.dataOver = true;
}
tmp.onmouseout = function(){
myKaRubberZoom.dataOver = false;
}
var batsuUrl = point.xml_overlay.urlBase + "common/images/batsu.gif";
point.div.canvas.appendChild(tmp);
$("infobox").style.width = "298px";
if(html != null && html != ""){
var tgtObj = getRawObject("infoboxmemo");
tgtObj.innerHTML = " ";
tgtObj.innerHTML += html;
slidePoint(point);
}else if(url != null && url != ""){
var tgtObj = getRawObject("infoboxmemo");
tgtObj.innerHTML = "loading .....";
/*var pars = "";
var objajax = new Ajax.Request(url,{
method: "get",
parameters: pars,
onComplete:function(ores){
$("infoboxmemo").innerHTML = "";
$("infoboxmemo").innerHTML += ores.responseText;
slidePoint(point);
}
});
*/
call(url,null,function(res){
var tgtObj = getRawObject("infoboxmemo");
tgtObj.innerHTML = " ";
tgtObj.innerHTML += res;
slidePoint(point);
});
}else if(iframeSrc != null && iframeSrc != ""){
var xsize = "";
var ysize = "";
if(iframeWidth !=null && iframeWidth !=""){
xsize= " width:" + (iframeWidth-20) + "px;";
$("infobox").style.width = iframeWidth + "px";
}
if(iframeHeight !=null && iframeHeight !=""){
ysize=" height:" + (iframeHeight-20) + "px;";
$("infobox").style.height = iframeHeight + "px";
}
var stylesrc = "";
if(xsize != "" || ysize != ""){
stylesrc = "style=\"" + xsize + ysize + "\"";
}
var tgtObj = getRawObject("infoboxmemo");
tgtObj.innerHTML = " ";
tgtObj.innerHTML += "";
slidePoint(point);
}
};
function slidePoint(point){
boxTop = getTopPos("infobox",ICTMAP.IctMap.CONST_VIEWPORT_ID);
boxLeft = getLeftPos("infobox",ICTMAP.IctMap.CONST_VIEWPORT_ID);
boxRight = boxLeft+getObjectWidth("infobox");
boxBottom = getTopPos("infobox",ICTMAP.IctMap.CONST_VIEWPORT_ID)+getObjectHeight("infobox")+20;
vy = point.xml_overlay.kaMap.viewportHeight;
vx = point.xml_overlay.kaMap.viewportWidth;
//alert("boxLeft="+boxLeft+"boxRight="+boxRight+"boxBottom="+boxBottom+"vy="+vy+"vx="+vx);
var slideY = 0,slideX = 0;
if(boxTop < 10) slideY = -(boxTop) + 50;
if(boxBottom > vy) slideY = -((boxBottom-vy)+80);
if(boxLeft < 10){
slideX = -(boxLeft)+10;
}else if(boxRight > vx){
slideX = -((boxRight-vx)+30);
}
if(vx < 500 || vy < 500){
return;
}
//alert("slideX="+slideX);
//alert("slideY="+slideY);
if(slideY != 0 || slideX != 0){
point.xml_overlay.kaMap.slideBy(slideX,slideY); // 地図を移動
point.xml_overlay.kaMap.automove = true;
}
};
function popuppoint(id,flg){
obj = "xmlovr_p"+id+"_div";
var tgtObj = getRawObject(obj);
if(flg){
if(tgtObj) tgtObj.style.zoom = 1.8;
}else{
if(tgtObj) tgtObj.style.zoom = 1;
}
};
function getTopPos(inputObjname,toboj){
inputObj = getRawObject(inputObjname);
var returnValue = inputObj.offsetTop;
while((inputObj = inputObj.offsetParent) != null){
returnValue += inputObj.offsetTop;
if(inputObj.id == toboj){
break;
}
}
return returnValue;
};
function getLeftPos(inputObjname,toboj){
inputObj = getRawObject(inputObjname);
var returnValue = inputObj.offsetLeft;
while((inputObj = inputObj.offsetParent) != null){
if(inputObj.id == toboj){
break;
}
returnValue += inputObj.offsetLeft;
}
return returnValue;
};
/**
* This object is a single point on the overlay.
* The object hold the div and all the stuff to draw and move the point
* (symbol, label, icon, etc.).
*
* pid The point ID (string)
* xml_overlay The kaXmlOverlay object owner of this point
* opts EventFunc
*/
function kaXmlPoint(pid, xml_overlay,sid,opts,pointName) {
this.xml_overlay = xml_overlay;
this.pid = pid;
this.opts = opts;
this.divId = this.xml_overlay.getDivId(pid);
this.geox = 0;
this.geoy = 0;
this.shown = false;
this.graphics = new Array();
this.div = document.createElement('div');
this.div.setAttribute('id', this.divId);
if(!pid.match(/^user_[0-9]*/)){ // 標準ポイント
this.onclickflg = false;
this.pointtype = "KIHON";
}else{ // ユーザポイント
this.pointtype = "USER";
}
if(this.pointtype == "KIHON"){
this.div.setAttribute('class', 'overlaysymbol');
this.div.style.zIndex=250;
}else if(this.pointtype == "USER"){
this.div.setAttribute('class', 'usersymbol');
this.div.style.zIndex=500;
}
if(this.opts != null){
//this.div.setAttribute('class', 'overlaysymbol');
this.onclickflg = true;
}
this.sid = sid;
this.div.sid = sid;
this.div.pointName = pointName;
};
function clearOverlaysymbolhtml(){
/*$$(".overlaysymbolhtml").each(function(overlaysymbolhtml) {
Element.remove(overlaysymbolhtml);
});*/
getRawObject("pointinfo").style.visibility = 'hidden';
getRawObject("pointinfo").style.display = 'none';
getRawObject("infoboxmemo").innerHTML = "";
myKaRubberZoom.dataOver = false;
};
/**
* Show the point in the specified geo-position.
*/
kaXmlPoint.prototype.placeOnMap = function( x, y ) {
if (!this.shown) {
this.geox = x;
this.geoy = y;
this.xml_overlay.kaMap.addObjectGeo( this.xml_overlay.overlayCanvas, x, y, this.div );
this.shown = true;
}
};
/**
* Delete the point.
*/
kaXmlPoint.prototype.removeFromMap = function( ) {
if (this.shown) {
this.xml_overlay.kaMap.removeObject( this.div );
this.shown = false;
}
var i;
for (i=0; i
*/
kaXmlPoint.prototype.parse = function(point_element) {
var i;
var x = parseFloat(point_element.getAttribute("x"));
var y = parseFloat(point_element.getAttribute("y"));
var redraw_a = point_element.getAttribute("redraw");
var redraw = false;
if (redraw_a == "true") redraw = true;
if (!this.shown) {
this.placeOnMap(x,y);
this.shown = true;
} else {
this.setPosition(x,y);
// Need redraw?
if (!redraw) return;
// clear and redraw the point
this.clear();
}
// look for ihtml element
var ihtml_element = point_element.getElementsByTagName("ihtml");
for (i=0; i
*/
kaXmlPoint.prototype.parse2 = function(point_element) {
var i;
var x = parseFloat(point_element.x);
var y = parseFloat(point_element.y);
var redraw_a = point_element.redraw;
var redraw = false;
if (redraw_a == "true") redraw = true;
if (!this.shown) {
this.placeOnMap(x,y);
this.shown = true;
} else {
this.setPosition(x,y);
// Need redraw?
if (!redraw) return;
// clear and redraw the point
this.clear();
}
/*
// look for ihtml element
var ihtml_element = point_element.ihtml;
for (i=0; i= 1) return '';
if (_BrowserIdent_browser == "Netscape Navigator")
imageobject.style.MozOpacity=opacity;
else if (_BrowserIdent_browser == "Internet Explorer" && parseInt(this.version)>=4) {
//filter: alpha(opacity=50);
var tmp = imageobject.style.cssText;
tmp = "filter: alpha(opacity="+(opacity*100)+");" + tmp;
imageobject.style.cssText = tmp;
} else {
var tmp = imageobject.style.cssText;
tmp = "opacity: "+opacity+";" + tmp;
imageobject.style.cssText = tmp;
}
};
function _BrowserIdent_getPreferredImageType() {
if (_BrowserIdent_browser == "Netscape Navigator") return "P";
else if (_BrowserIdent_browser == "Opera") return "P";
else if (_BrowserIdent_browser == "Firefox") return "P";
else if (_BrowserIdent_browser == "Safari") return "P";
else if (_BrowserIdent_browser == "Konqueror") return "P";
else return "G"
};
function _BrowserIdent_getPreferredOpacity() {
if (_BrowserIdent_browser == "Netscape Navigator") return "server";
else if (_BrowserIdent_browser == "Firefox") return "server";
else if (_BrowserIdent_browser == "Opera") return "server";
else if (_BrowserIdent_browser == "Konqueror") return "server";
else return "client"
};
var xmlOverlayUseCanvas = true;
function _BrowserIdent_hasCanvasSupport() {
if (! xmlOverlayUseCanvas) return false;
if (_BrowserIdent_browser == "Internet Explorer") return true;
if (_BrowserIdent_browser == "Firefox") return true;
if (_BrowserIdent_browser == "Safari") return true;
//if (_BrowserIdent_browser == "Konqueror") return true;
//if (_BrowserIdent_browser == "Opera") return true;
return false;
};
function _BrowserIdent_newCanvas(parentNode) {
var el = document.createElement('canvas');
parentNode.appendChild(el);
if (typeof G_vmlCanvasManager != "undefined") {
el = G_vmlCanvasManager.initElement(el);
}
return el;
};
function _BrowserIdent_getCanvasContext(canvas) {
return canvas.getContext('2d');
};
function _BrowserIdent_setCanvasHW(canvas, height, width) {
canvas.width = width;
canvas.height = height;
};
_BrowserIdent();
var charset="";
// jsr_class.js
//
// JSONscriptRequest -- a simple class for making HTTP requests
// using dynamically generated script tags and JSON
//
// Author: Jason Levitt
// Date: December 7th, 2005
//
// A SECURITY WARNING FROM DOUGLAS CROCKFORD:
// "The dynamic
//
// function callbackfunc(jsonData) {
// alert('Latitude = ' + jsonData.ResultSet.Result[0].Latitude +
// ' Longitude = ' + jsonData.ResultSet.Result[0].Longitude);
// aObj.removeScriptTag();
// }
//
// request = 'http://api.local.yahoo.com/MapsService/V1/geocode?appid=YahooDemo&
// output=json&callback=callbackfunc&location=78704';
// aObj = new JSONscriptRequest(request);
// aObj.buildScriptTag();
// aObj.addScriptTag();
//
//
// Constructor -- pass a REST request URL to the constructor
//
function JSONscriptRequest(fullUrl) {
// REST request path
this.fullUrl = fullUrl;
// Keep IE from caching requests
this.noCacheIE = '&noCacheIE=' + (new Date()).getTime();
// Get the DOM location to put the script tag
this.headLoc = document.getElementsByTagName("head").item(0);
// Generate a unique script tag id
this.scriptId = 'JscriptId' + JSONscriptRequest.scriptCounter++;
};
// Static script ID counter
JSONscriptRequest.scriptCounter = 1;
// buildScriptTag method
//
JSONscriptRequest.prototype.buildScriptTag = function () {
// Create the script tag
this.scriptObj = document.createElement("script");
// Add script object attributes
this.scriptObj.setAttribute("type", "text/javascript");
this.scriptObj.setAttribute("charset", "utf-8");
this.scriptObj.setAttribute("src", this.fullUrl + this.noCacheIE);
this.scriptObj.setAttribute("id", this.scriptId);
};
// removeScriptTag method
//
JSONscriptRequest.prototype.removeScriptTag = function () {
// Destroy the script tag
if(this.scriptObj) this.headLoc.removeChild(this.scriptObj);
};
// addScriptTag method
//
JSONscriptRequest.prototype.addScriptTag = function () {
// Create the script tag
this.headLoc.appendChild(this.scriptObj);
};