    var svg ;
    var root ;
    var distancewindow, distancebox, distancetext ;
    var coordwindow, coordbox, coordtext, mousecoord=1 ;
    var labelwindow ;
    var labelbox ;
    var labeltext ;
    var infowindow ;
    var legend ;
    var infobox ;
    var zminenb = 1 ;
    var zmoutenb = 0 ;
    var pneastenb = 0 ;
    var pnwestenb = 0 ;
    var pnnorthenb = 0 ;
    var pnsouthenb = 0 ;
    var legendon = 0 ;
    var maxinfolines=16 ;
    var currentLevel=0 ;
    var windowselect=0 ;
    var featureselect=0 ;
    var polygonselect=0 ;
    var polylineDrawing=0 ;
    var simpleLineDrawing=0 ;
    var pathisempty=1;
    var selectedCount = 0 ;
    var selectwindow ;
    var windowisempty=1;
    var selectwindowresize=0 ;
    var freeDrawStarted=0;
    var freeDrawingPath ;
    var justClicked=0;
    var distanceMode="NONE";
    var onLineDraw=null, onPolylineDraw=null ;

    function initSVG(evt) 
    {
      svg = evt.target.parentNode ;
      root = svg.getElementById("root") ;
      coordwindow = svg.getElementById("coordwindow");
      coordbox = svg.getElementById("coordbox");
      coordtext = svg.getElementById("coordtext");
      distancewindow = svg.getElementById("distancewindow");
      distancebox = svg.getElementById("distancebox");
      distancetext = svg.getElementById("distancetext");
      labelwindow = svg.getElementById("labelwindow");
      labelbox = svg.getElementById("labelbox");
      labeltext = svg.getElementById("labeltext");
      infobox = svg.getElementById("infobox");
      legend = svg.getElementById("legend");
      infowindow = svg.getElementById("infowindow");
      selectwindow = svg.getElementById("selectwindow") ;
      freeDrawingPath = svg.getElementById("freedrawpath");
      initSelectedIdList() ;
    }
    function setOnSimpleLineDraw(func)
    {
      onLineDraw = func ;
    }
    function setOnPolylineDraw(func)
    {
      onPolylineDraw = func ;
    }
    function switchInfoStatus()
    {
      if(infoon==0)
      {
        infoon=1 ;
        changeColor('info', 'red');
      }
      else
      {
        infoon=0 ;
        changeColor('info', '#cceeff');
        hideInfoWindow();
      }
    }
    function switchLegendStatus()
    {
      if(legendon==0 && legend!=null)
      {
        legendon=1 ;
        changeColor('lgdbutton', 'red');
        legend.setAttribute("visibility", "visible") ;
      }
      else if(legend!=null)
      {
        legendon=0 ;
        changeColor('lgdbutton', '#cceeff');
        legend.setAttribute("visibility", "hidden") ;
      }
    }
    function hideInfoWindow()
    {
      infobox.setAttribute("visibility", "hidden") ;
      for(var i=1; i<=maxinfolines; i++)
      {
        var infotext = svg.getElementById("infotext"+i) ;
        infotext.setAttribute("visibility", "hidden");
      }
    }
    function displayInfoLabel(evt)
    {
      if(infoon)
        displayInfo(evt);
      else
        displayLabel(evt);
    }
    function displayInfo(evt)
    {
      if(infoon==0)
        return ;
      var maxlen = 0 ;
      var len = 0 ;
      var info = evt.target.getAttribute("info") ;
      if(info==null || info.length==0)
        return ;
      var lines = info.split("\\n");
      var linecnt = 0 ;
      var i=0 ;
      var infowidth ;
      var infoheight ;

      for(i=0; i<lines.length && linecnt<maxinfolines; i++)
      {
        var text = lines[i] ;
        if(text.length>0)
        {
          linecnt++;
          var infotext = svg.getElementById("infotext"+linecnt) ;
          var data = infotext.firstChild ;
          data.data = text;
	    len=infotext.getComputedTextLength();
          if(len>maxlen)
            maxlen=len ;
          infotext.setAttribute("visibility", "visible");
        }
      }
      if(linecnt>0)
      {
        infobox.setAttribute("visibility", "visible");
        infowidth = maxlen+10 ;
        infoheight = linecnt*12+10 ;
        infobox.setAttribute("width", infowidth);
        infobox.setAttribute("height", infoheight) ;
        for(i=linecnt+1; i<=maxinfolines; i++)
        {
          var infotext = svg.getElementById("infotext"+i) ;
          infotext.setAttribute("visibility", "hidden");
        }
        var lx = evt.clientX+20 ;
        var ly = evt.clientY+5 ;
        if(lx+infowidth+5>width)
          lx = width-infowidth-5 ;
        if(ly+infoheight+5>height)
          ly = height-infoheight-5 ;
        infowindow.setAttribute("transform", "translate("+lx+","+ly+")") ;
      }
    }
    function hideTheme(theme)
    {
      if(theme==null)
        return ;
      var t = svg.getElementById("theme_"+theme) ;
      if(t!=null)
      {
        t.setAttribute("visibility", "hidden") ;
        var children =t.childNodes;
        for(i=0; i<children.length; i++)
        {
          var e = children.item(i) ;
          if(e!=null)
          {
            if(e.nodeName=="#text")
              continue ;
            var level = e.getAttribute("zoom_level") ;
            e.setAttribute("th", "y") ;
            if(level == currentLevel || level=="")
              e.setAttribute("visibility", "hidden") ;
          }
        }
      }
      t = svg.getElementById("label_"+theme) ;
      if(t!=null)
      {
        var children =t.childNodes;
        for(i=0; i<children.length; i++)
        {
          var e = children.item(i) ;
          if(e!=null)
          {
            var level = e.getAttribute("zoom_level") ;
            e.setAttribute("th", "y") ;
            if(level == currentLevel || level=="")
              e.setAttribute("visibility", "hidden") ;
          }
        }
      }
    }
    function showTheme(theme)
    {
      if(theme==null)
        return ;
      var t = svg.getElementById("theme_"+theme) ;
      if(t!=null)
      {
        t.setAttribute("visibility", "visible") ;
        var children =t.childNodes;
        for(i=0; i<children.length; i++)
        {
          var e = children.item(i) ;
          if(e!=null)
          {
            if(e.nodeName=="#text")
              continue ;
            var level = e.getAttribute("zoom_level") ;
            e.setAttribute("th", "n") ;
            if(level == "")
            {
              var lscale = e.getAttribute("max_scale") ;
              if(lscale <= scale)
                e.setAttribute("visibility", "visible") ;
            }
            else if(level == currentLevel)
              e.setAttribute("visibility", "visible") ;
          }
        }
      }
      t = svg.getElementById("label_"+theme) ;
      if(t!=null)
      {
        var children =t.childNodes;
        for(i=0; i<children.length; i++)
        {
          var e = children.item(i) ;
          if(e!=null)
          {
            var level = e.getAttribute("zoom_level") ;
            e.setAttribute("th", "n") ;
            if(level == "")
            {
              var lscale = e.getAttribute("max_scale") ;
              if(lscale <= scale)
                e.setAttribute("visibility", "visible") ;
            }
            else if(level == currentLevel)
              e.setAttribute("visibility", "visible") ;
          }
        }
      }
    }
    function changeNonLineLabelSize()
    {
      for(i=0; i<nonLineLabelLevelGroupCnt; i++)
      {
        var textId = "nlg"+i ;
        var text = svg.getElementById(textId) ;
        if(text!=null)
        {
          var level = text.getAttribute("zoom_level") ;
          if(level != currentLevel)
            text.setAttribute("visibility", "hidden") ;
          else if(text.getAttribute("th")=="n")
            text.setAttribute("visibility", "visible") ;
        }
      }
    }
    function changeScaleBar()
    {
      for(i=0; i<zoomLevels; i++)
      {
        var scalebar = svg.getElementById("scalebar"+i) ;
        if(scalebar!=null)
        {
          if(i != currentLevel)
            scalebar.setAttribute("visibility", "hidden") ;
          else 
            scalebar.setAttribute("visibility", "visible") ;
        }
      }
    }
    function changeFontSize()
    {
      for(var i=0; i<labelGroupCnt; i++)
      {
        var textId = "l" + i ;
        var text = svg.getElementById(textId) ;
        if(text!=null)
        {
          var size = text.getAttribute("font-size")*scale ;
          var orgSize = text.getAttribute("orig-size") ;
          var fixedSize = text.getAttribute("size-fixed") ;
          if(fixedSize!="true")

          {
            if(orgSize==null || orgSize=="")
            {
              orgSize = text.getAttribute("font-size") ;
              text.setAttribute("orig-size", orgSize) ;
            }
            var newsize=orgSize/scale ;
            text.setAttribute("font-size", newsize) ;
          }
        }
      }
      for(i=0; i<labelLevelGroupCnt; i++)
      {
        var textId = "lg"+i ;
        var text = svg.getElementById(textId) ;
        if(text!=null)
        {
          var maxScale = text.getAttribute("max_scale") ;
          if(maxScale <= scale && text.getAttribute("th")!="y")
            text.setAttribute("visibility", "visible") ;
          else
            text.setAttribute("visibility", "hidden") ;
        }
      }
    }
    function setZoomRatio(s)
    {
      scale = s ; 
      var w = width/scale ;
      var h = height/scale ;
      var tmpscale = scale;
      for(i=0;;i++)
      {
        if(tmpscale<=1)
        {
          currentLevel=i ;
          break ;
        }
        else
          tmpscale = tmpscale/zoomFactor ;
      }
      changeFontSize();
      changeNonLineLabelSize();
      changeScaleBar();
      root.setAttribute("viewBox", (cx-w/2)+' '+(cy-h/2)+' '+w+' '+h) ;
    }
    function zoomin()
    {
      if(zminenb==0)
        return ;
      if(scale<maxScale)
      {
        currentLevel++ ;
        scale = scale*zoomFactor;
        zmoutenb = 1 ;
        pneastenb = 1 ;
        pnwestenb = 1 ;
        pnnorthenb = 1 ;
        pnsouthenb = 1 ;
        changeColor('zoomout', '#cceeff');
        changeColor('paneast', '#cceeff');
        changeColor('panwest', '#cceeff');
        changeColor('pannorth', '#cceeff');
        changeColor('pansouth', '#cceeff');
      }
      else
      {
        zminenb = 0 ;
        changeColor('zoomin', 'grey');
      }

      var w = width/scale ;
      var h = height/scale ;
      changeFontSize() ;
      changeNonLineLabelSize();
      changeScaleBar();
      root.setAttribute("viewBox", (cx-w/2)+' '+(cy-h/2)+' '+w+' '+h) ;
    }
    function zoomout()
    {
      if(zmoutenb==0)
        return ;
      if(zminenb==0)
        changeColor('zoomin', '#cceeff');
      zminenb = 1 ;
      scale = scale/zoomFactor ;
      currentLevel-- ;
      if(scale<=1)
      {
        currentLevel=0 ;
        scale=1 ;
        cx=ocx ;
        cy=ocy ;
        zmoutenb = 0 ;
        pneastenb = 0 ;
        pnwestenb = 0 ;
        pnnorthenb = 0 ;
        pnsouthenb = 0 ;
        changeColor('zoomout', 'grey');
        changeColor('paneast', 'grey');
        changeColor('panwest', 'grey');
        changeColor('pannorth', 'grey');
        changeColor('pansouth', 'grey');
      }
      var w = width/scale ;
      var h = height/scale ;
      if(cx+w/2>width)
        cx=width-w/2 ;
      else if(cx-w/2<0)
        cx=w/2 ;
      if(cy+h/2>height)
        cy=height-h/2 ;
      else if(cy-h/2<0)
        cy=h/2 ;
      changeFontSize() ;
      changeNonLineLabelSize();
      changeScaleBar();
      root.setAttribute("viewBox", (cx-w/2)+' '+(cy-h/2)+' '+w+' '+h) ;
    }
    function recenter(x, y)
    {
      var w = width/scale ;
      var h = height/scale ;
      cx = x ;
      cy = y ;
      root.setAttribute("viewBox", (x-w/2)+' '+(y-h/2)+' '+w+' '+h) ;
    }
    function panwest()
    {
      if(pnwestenb==0)
        return ;
      else
      {
        pneastenb=1 ;
        changeColor('paneast', '#cceeff');
      }
      var w = width/scale ;
      var h = height/scale ;
      cx = cx+width/2/scale ;
      if(cx+w/2>width)
      {
        cx=width-w/2 ;
        pnwestenb=0 ;
        changeColor('panwest', 'grey');
      }
      recenter(cx, cy) ;
    }
    function paneast()
    {
      if(pneastenb==0)
        return ;
      else
      {
        pnwestenb=1 ;
        changeColor('panwest', '#cceeff');
      }
      var w = width/scale ;
      var h = height/scale ;
      cx = cx-width/2/scale ;
      if(cx-w/2<0)
      {
        cx=w/2 ;
        pneastenb=0 ;
        changeColor('paneast', 'grey');
      }
      recenter(cx, cy) ;
    }
    function pansouth()
    {
      if(pnsouthenb==0)
        return ;
      else
      {
        pnnorthenb=1 ;
        changeColor('pannorth', '#cceeff');
      }
      var w = width/scale ;
      var h = height/scale ;
      cy = cy+height/2/scale ;
      if(cy+h/2>height)
      {
        cy=height-h/2 ;
        pnsouthenb=0;
        changeColor('pansouth', 'grey');
      }
      recenter(cx, cy) ;
    }
    function pannorth()
    {
      if(pnnorthenb==0)
        return ;
      else
      {
        pnsouthenb=1 ;
        changeColor('pansouth', '#cceeff');
      }
      var w = width/scale ;
      var h = height/scale ;
      cy = cy-height/2/scale ;
      if(cy-h/2<0)
      {
        cy=h/2 ;
        pnnorthenb=0;
        changeColor('pannorth', 'grey');
      }
      recenter(cx, cy) ;
    }
    function changeColor(id, color)
    {
      var elem = svg.getElementById(id) ;
      if(elem!=null)
        elem.setAttribute("fill", color);
    }
    function changeStatus(id, status)
    {
      if(id=="zoomin")
      {
        if(zminenb==1)
        {
          if(status=="on")
            changeColor(id, "red") ;
          else
            changeColor(id, "#cceeff") ;
        }
        else 
          changeColor(id, "grey") ;
      }
      else if(id=="zoomout")
      {
        if(zmoutenb==1)
        {
          if(status=="on")
            changeColor(id, "red") ;
          else
            changeColor(id, "#cceeff") ;
        }
      }
      else if(id=="paneast")
      {
        if(pneastenb==1)
        {
          if(status=="on")
            changeColor(id, "red") ;
          else
            changeColor(id, "#cceeff") ;
        }
      }
      else if(id=="panwest")
      {
        if(pnwestenb==1)
        {
          if(status=="on")
            changeColor(id, "red") ;
          else
            changeColor(id, "#cceeff") ;
        }
      }
      else if(id=="pannorth")
      {
        if(pnnorthenb==1)
        {
          if(status=="on")
            changeColor(id, "red") ;
          else
            changeColor(id, "#cceeff") ;
        }
      }
      else if(id=="pansouth")
      {
        if(pnsouthenb==1)
        {
          if(status=="on")
            changeColor(id, "red") ;
          else
            changeColor(id, "#cceeff") ;
        }
      }
    }
    function displayLabel(evt)
    {
      var label = evt.target.getAttribute("label") ;
      var data = labeltext.firstChild ;
      data.data = label;
      var len=labeltext.getComputedTextLength();
      labelbox.setAttribute("width", len+10) ;
      var lx = evt.clientX+15 ;
      var ly = evt.clientY+15 ;
      if(lx+len+10>width)
        lx = width-len-20 ;
      if(ly+20>height)
        ly = height-20 ;
      labelwindow.setAttribute("transform", "translate("+lx+","+ly+")") ;
      labelwindow.setAttribute("visibility", "visible") ;
    }
    function hideInfoLabel()
    {
      labelwindow.setAttribute("visibility", "hidden") ;
      hideInfoWindow();
    }
    function updateMouseCoord(evt)
    {
      var coord=getUserCoordinate(evt.clientX,evt.clientY);
      var data = coordtext.firstChild;
      data.data = Math.round(coord[0]*100000)/100000.+","+Math.round(coord[1]*100000)/100000.;
      var len=coordtext.getComputedTextLength();
      coordbox.setAttribute("width", len+10) ;
    }
    function hideMouseCoord()
    {
      mousecoord = 0 ;
      coordwindow.setAttribute("visibility", "hidden") ;
    }
    function showMouseCoord()
    {
      mousecoord = 1 ;
      coordwindow.setAttribute("visibility", "visible") ;
    }
    function updateDistance(evt)
    {
      var data = distancetext.firstChild;
      var distance = getPathDistance() ;
      var unit="" ;
      if(useunit==1)
      {
        if(distanceMode=='METRIC')
        {
          if(distance>1000)
          {
            distance = distance/1000.;
            unit="km";
          }
          else
            unit="m";
        }
        else if(distanceMode=='US')
        {
          distance=distance*3.2808399;
          if(distance>5280)
          {
            distance = distance/5280 ;
            unit="mi";
          }
          else
            unit="ft";
        }
        if(distance>1)
          distance = Math.round(distance*100)/100.
      }
      data.data = "Distance:"+distance+unit;
      var len=distancetext.getComputedTextLength();
      distancebox.setAttribute("width", len+10) ;
    }
    function hideDistance()
    {
      distancewindow.setAttribute("visibility", "hidden") ;
    }
    function showDistance(mode)
    {
      distanceMode = mode ;
      var data = distancetext.firstChild;
      data.data = "Distance:0";
      distancewindow.setAttribute("visibility", "visible") ;
      updateDistance(null);
    }
    function showLoadingBar()
    {
      var bar = svg.getElementById("loadingbar") ;
      bar.setAttribute("visibility", "visible") ;
    }
    function disableFeatureSelect()
    {
      featureselect = 0 ;
    }
    function disablePolygonSelect()
    {
      polygonselect=0;
      pathisempty=1;
      freeDrawingPath.setAttribute("visibility", "hidden");
    }
    function disableRectangleSelect()
    {
      windowselect = 0 ;
      windowisempty=1;
      selectwindow.setAttribute("visibility", "hidden") ;
    }
    function disableSimpleLineDrawing()
    {
      simpleLineDrawing=0 ;
      pathisempty=1;
      freeDrawingPath.setAttribute("d","");
      freeDrawingPath.setAttribute("visibility", "hidden");
    }
    function disablePolylineDrawing()
    {
      polylineDrawing=0 ;
      pathisempty=1;
      freeDrawingPath.setAttribute("d","");
      freeDrawingPath.setAttribute("visibility", "hidden");
    }
    function enableSimpleLineDrawing()
    {
      simpleLineDrawing = 1 ;
      pathisempty=1;
      freeDrawStarted = 0 ;
      disablePolylineDrawing() ;
      disableFeatureSelect() ;
      disableRectangleSelect();
      disablePolygonSelect();
    }
    function enablePolylineDrawing()
    {
      polylineDrawing = 1 ;
      pathisempty=1;
      freeDrawStarted = 0 ;
      freeDrawingPath.setAttribute("fill", "none");
      disableSimpleLineDrawing() ;
      disableFeatureSelect() ;
      disableRectangleSelect();
      disablePolygonSelect();
    }
    function enableFeatureSelect()
    {
      featureselect = 1 ;
      disablePolylineDrawing();
      disableSimpleLineDrawing();
      disableRectangleSelect();
      disablePolygonSelect();
    }
    function enableRectangleSelect()
    {
      windowselect = 1 ;
      windowisempty=1;
      disableFeatureSelect();
      disablePolylineDrawing();
      disableSimpleLineDrawing();
      disablePolygonSelect();
    }
    function enablePolygonSelect()
    {
      freeDrawingPath.setAttribute("fill", "grey");
      freeDrawingPath.setAttribute("opacity", "0.5");
      polygonselect=1;
      pathisempty=1;
      freeDrawStarted=0;
      disableFeatureSelect();
      disablePolylineDrawing();
      disableSimpleLineDrawing();
      disableRectangleSelect() ;
    }
    function startSelect(evt)
    {
      if(windowselect==0 || evt.button!=0)
        return ;
      windowisempty=1;
      startx = (evt.clientX-width/2.0)/scale+cx;
      starty = (evt.clientY-height/2.0)/scale+cy;
      selectwindow.setAttribute("x", startx) ;
      selectwindow.setAttribute("y", starty) ;
      selectwindow.setAttribute("width", 0) ;
      selectwindow.setAttribute("height", 0) ;
      selectwindow.setAttribute("visibility", "visible") ;
      selectwindowresize = 1 ;
    }
    function moveMouse(evt)
    {
      if(mousecoord==1)
        updateMouseCoord(evt);
      if((windowselect==0||selectwindowresize==0)&&polygonselect==0&& 
         simpleLineDrawing==0&&polylineDrawing==0)
        return ;
      var tx = (evt.clientX-width/2.0)/scale+cx;
      var ty = (evt.clientY-height/2.0)/scale+cy;
      if(polygonselect==1||polylineDrawing==1||simpleLineDrawing)
      {
        if(freeDrawStarted==0)
          return ;
        var coords = freeDrawingPath.getAttribute("d") ;
        var lidx = coords.lastIndexOf("L")
        if(lidx==-1||justClicked==1&&(polylineDrawing==1||polygonselect==1))
          coords = coords+" L"+tx+","+ty;
        else
          coords = coords.substring(0,lidx)+"L"+tx+","+ty;
        if(justClicked==1&&simpleLineDrawing==1&&lidx>0)
        {
          freeDrawStarted = 0 ;
          pathisempty=0;
          if(onLineDraw!=null)
            eval(onLineDraw+"()") ;
        }
        freeDrawingPath.setAttribute("d", coords);
        justClicked=0;
        if(simpleLineDrawing==1||polylineDrawing==1)
          updateDistance(evt) ;
      }
      else
      {
        if(tx<startx)
        {
          selectwindow.setAttribute("x", tx) ;
          selectwindow.setAttribute("width", (startx-tx)) ;
        }
        else
          selectwindow.setAttribute("width", (tx-startx)) ;
        if(ty<starty)
        {
          selectwindow.setAttribute("y", ty) ;
          selectwindow.setAttribute("height", (starty-ty)) ;
        }
        else
          selectwindow.setAttribute("height", (ty-starty)) ;
      }
    }
    function endSelect(evt)
    {
      if(windowselect==0 || evt.button!=0)
        return ;

      selectwindowresize = 0 ;
      endx = (evt.clientX-width/2.0)/scale+cx;
      endy = (evt.clientY-height/2.0)/scale+cy;
      if(startx-endx>-1 && startx-endx<1 && starty-endy>-1 && starty-endy<1)
        return ;
      else
      {
        windowisempty=0;
        onRectangleSelect(evt);
      }
    }
    function freeDraw(evt)
    {
      var x = (evt.clientX-width/2.0)/scale+cx;
      var y = (evt.clientY-height/2.0)/scale+cy;
      justClicked=1 ;
      if(freeDrawStarted==0)
      {
        freeDrawStarted=1 ;
        pathisempty=1;
        drawStartX = x ;
        drawStartY = y ;
        lfx=x;lfy=y;
        freeDrawingPath.setAttribute("visibility","visible");
        freeDrawingPath.setAttribute("d", "M"+drawStartX+","+drawStartY);
      }
      else
      {
        if(x-drawStartX<3&&x-drawStartX>-3 && y-drawStartY<3&&y-drawStartY>-3)
        {
          var d=freeDrawingPath.getAttribute("d");
          var lidx=d.lastIndexOf("L");
          freeDrawingPath.setAttribute("d", d.substring(0,lidx)+"L"+drawStartX+","+drawStartY);
          freeDrawStarted=0 ;
          pathisempty=0;
          if(polygonselect==1)
            onPolygonSelect(evt) ;
          else if(polylineDrawing==1 && onPolylineDraw!=null)
            eval(onPolylineDraw+"()");
        }
        else if(x-lfx<1&&x-lfx>-1&&y-lfy<1&&y-lfy>-1)
        {
          freeDrawStarted=0 ;
          pathisempty=0;
          if(polygonselect==1)
          {
            freeDrawingPath.setAttribute("d", freeDrawingPath.getAttribute("d")+"L"+drawStartX+","+drawStartY);
            onPolygonSelect(evt) ;
          }
          else if(polylineDrawing==1 && onPolylineDraw!=null)
            eval(onPolylineDraw+"()") ;
        }
        else
        {
          lfx=x;lfy=y;
        }
      }
    }
    function getScreenSelectRectangle()
    {
      if(windowisempty==1)
        return null ;
      var result=new Array(4) ;
      result[0]=startx ;
      result[1]=starty ;
      result[2]=endx ;
      result[3]=endy ;
      return result;
    }
    function getThemeName(node)
    {
      if(node!=null)
      {
        var parent = node.parentNode ;
        while(parent!=null)
        {
          var pid = parent.getAttribute("id") ;
          if(pid)
          {
            if(pid.indexOf("theme_")==0)
              return pid.substring(6);
          }
          parent = parent.parentNode ;
        }
        return null ;
      }
      else
        return null ;
    }
    function getThemeIdx(theme)
    {
      for(i=0; i<selectableThemeList.length; i++)
        if(selectableThemeList[i]==theme)
          return i ;
      return -1 ;
    }
    function getNodes(theme, key)
    {
      var elem = svg.getElementById("theme_"+theme) ;
      if(elem==null)
        return null ;
      var children = elem.childNodes ;
      if(children==null || children.length==0)
        return null;
      var result = new Array(zoomLevels) ;
      var count = 0 ;
      for(i=0; i<children.length; i++)
      {
        var node = children.item(i) ;
        if(node.getAttribute('key')==null || node.getAttribute('key')=='')
        {
          var grandChildren = node.childNodes ;
          if(grandChildren!=null && grandChildren.length>0)
          {
            for(j=0; j<grandChildren.length; j++)
            {
              node = grandChildren.item(j) ;
              if(node.getAttribute('key')==key)
              {
                result[count] = node ;
                count ++ ;
                break ;
              }
            }
          }
        }
        else if(node.getAttribute('key')==key)
        {
          result[count] = node ;
          count ++ ;
          break ;
        }
      }
      if(count==0)
        return null ;
      else
        return result ;
    }
    function selectFeature(theme, id)
    {
      var tidx = getThemeIdx(theme) ;
      var nodes = getNodes(theme, id) ;
      var found = 0 ;
      if(nodes==null)
        return ;
      var i=0 ;
      var idList = selectedIdList[tidx] ;
      for(; i<selectedCountList[tidx]; i++)
        if(idList[i]==id)
        {
          found = 1 ;
          break ;
        }
      if(found==1)
      {
        for(;i<selectedCountList[tidx]-1; i++)
          idList[i] = idList[i+1] ;
        selectedCountList[tidx] -- ;
      }
      else
      {
        idList[selectedCountList[tidx]] = id ;
        selectedCountList[tidx] ++ ;
      }
      var j=0 ;
      for(; j<zoomLevels; j++)
      {
        var elem = nodes[j] ;
        if(elem==null)
          return ;
        var cclass = elem.getAttribute('class') ;
        var sclass = elem.getAttribute('sclass');
        if(!cclass || !sclass || cclass=="" || sclass=="")
        {
          cclass = elem.parentNode.getAttribute('class') ;
          sclass = elem.parentNode.getAttribute('sclass') ;
        }
        if(found==1)
        {
          if(sclass && sclass!="" || elem.getAttribute('xlink:href')==null || elem.getAttribute('xlink:href')=='')
          { 
            elem.setAttribute('class', sclass) ;
            elem.setAttribute('sclass', cclass);
          }
          else
            elem.setAttribute('opacity', '1') ;
        }
        else
        {
          if(sclass && sclass!="" || elem.getAttribute('xlink:href')==null || elem.getAttribute('xlink:href')=='')
          {
            elem.setAttribute('class', sclass) ;
            elem.setAttribute('sclass', cclass);
          }
          else
            elem.setAttribute('opacity', '0.4') ;
        }
      }
    }
    function select(evt)
    {
      if(evt.button!=0)
        return ;
      if(featureselect==0)
        return ;
      else
      {
        var elem = evt.target ;
        var themeName = getThemeName(elem) ;
        var id = elem.getAttribute('key') ;
        selectFeature(themeName, id) ;
      }
    }
    function getInfo(theme, key)
    {
      var nodes = getNodes(theme, key) ;
      if(nodes==null)
        return null ;
      var elem = nodes[0] ;
      if(elem==null)
        return null ;
      else
        return elem.getAttribute('info') ;
    }
    function getSelectedIdList(theme)
    {
      var idx = getThemeIdx(theme) ;
      if(idx>=0)
      {
        if(selectedCountList[idx]>0)
        {
          var result = new Array(selectedCountList[idx]) ;
          var idList = selectedIdList[idx] ;
          for(i=0; i<selectedCountList[idx]; i++)
            result[i] = idList[i]
          return result ;
        }
        else
          return null ;
      }
      else
        return null ;
    }
    function getPathDistance()
    {
      var d=freeDrawingPath.getAttribute("d");
      var count=0;
      for(i=0;i<d.length;i++)
      {
        if(d.charAt(i)=='M' ||d.charAt(i)=='L')
          count++ ;
      }
      var j=0,sidx=0,x,y,lx,ly,distance=0;
      for(i=0;i<d.length;i++)
      {
        if(d.charAt(i)=='M' ||d.charAt(i)=='L')
          sidx=i+1;
        else if(d.charAt(i)==',')
        {
          x=d.substring(sidx,i);
          sidx=i+1 ;
        }
        else if(d.charAt(i)==' ')
        {
          y=d.substring(sidx,i);
          coord=getUserCoordFromSVGCoord(x,y);
          if(j>0)
            distance = distance+getDistance(lx,ly,coord[0],coord[1]) ;
          lx=coord[0];ly=coord[1];
          j=j+2;
        }
      }
      y=d.substring(sidx,i);
      coord=getUserCoordFromSVGCoord(x,y);
      if(count>1)
        distance = distance+getDistance(lx,ly,coord[0],coord[1]) ;
      return distance ;
    }
    function getSelectRectangle()
    {
      if(windowisempty==1)
        return null ;
      var p1=getUserCoordFromSVGCoord(startx, starty);
      var p2=getUserCoordFromSVGCoord(endx, endy);
      var result=new Array(4) ;
      result[0]=p1[0];
      result[1]=p1[1];
      result[2]=p2[0];
      result[3]=p2[1];
      return result;
    }
    function setSelectRectangle(coords)
    {
      var p1=getSVGCoordinate(coords[0], coords[1]);
      var p2=getSVGCoordinate(coords[2], coords[3]);
      startx=p1[0];starty=p1[1];
      endx=p2[0];endy=p2[1];
      windowisempty=0;
      selectwindow.setAttribute("x", p1[0]) ;
      selectwindow.setAttribute("y", p1[1]) ;
      selectwindow.setAttribute("width", p2[0]-p1[0]) ;
      selectwindow.setAttribute("height", p2[1]-p1[1]) ;
      selectwindow.setAttribute("visibility", "visible") ;
    }
    function getLinePath()
    {
      return getSelectPolygon();
    }
    function getSelectPolygon()
    {
      if(pathisempty==1)
        return null ;
      var d=freeDrawingPath.getAttribute("d");
      var count=0;
      for(i=0;i<d.length;i++)
      {
        if(d.charAt(i)=='M' ||d.charAt(i)=='L')
          count++ ;
      }
      var result=new Array(count) ;
      var j=0,sidx=0,x,y;
      for(i=0;i<d.length;i++)
      {
        if(d.charAt(i)=='M' ||d.charAt(i)=='L')
          sidx=i+1;
        else if(d.charAt(i)==',')
        {
          x=d.substring(sidx,i);
          sidx=i+1 ;
        }
        else if(d.charAt(i)==' ')
        {
          y=d.substring(sidx,i);
          coord=getUserCoordFromSVGCoord(x,y);
          result[j]=coord[0];result[j+1]=coord[1];
          j=j+2;
        }
      }
      y=d.substring(sidx,i);
      coord=getUserCoordFromSVGCoord(x,y);
      result[j]=coord[0];result[j+1]=coord[1];
      return result ;
    }
    function setLinePath(coords)
    {
      setFreeDrawPath(coords, 0);
    }
    function setSelectPolygon(coords)
    {
      setFreeDrawPath(coords, 1);
    }
    function setFreeDrawPath(coords, polygon)
    {
      pathisempty=0;
      var d='' ;
      for(i=0;i<coords.length;i=i+2)
      {
        var p=getSVGCoordinate(coords[i], coords[i+1]);
        if(i==0)
          d='M' ;
        else
          d=d+' L' ;
        d=d+p[0]+','+p[1];
      }
      if(polygon==1)
        freeDrawingPath.setAttribute("fill", "grey");
      else
        freeDrawingPath.setAttribute("fill", "none");
      freeDrawingPath.setAttribute("d", d) ;
      freeDrawingPath.setAttribute("visibility", "visible") ;
    }
