GoogleMapの地図上にPolygonで矢印を引く

GoogleMapの地図上にPolygonで矢印を書いてみる。

似たようなのにSymbolみたいなのもあるけど、これだと少し細いのでPolygonで愚直に引いてみる。

と言っても、↑矢印をプログラムで描く;単純ベクトル加算法に紹介されている方法をGoogle Mapに置き換えただけ。なんかもう少しマシな方法がありそうだけど、とりあえず。

続きを読む →

自前で逆ジオコーディングをやってみる

概要

住所から地図上の位置情報(緯度、経度)を求めることをジオコーディング、その逆に地図上の位置情報から住所を求めることを逆ジオコーディング(リバース ジオコーディング)というらしい。

そんな面倒な処理は、普通Google Geocoding APIなんかの外部のサービスを利用すればよいのだけど、そういうのが使えない状況ってのがたまにある。さてどうするかというのが今回の問題。

結果としては、国土交通省が位置参照情報ダウンロードサービスで提供している街区レベル位置参照情報を使って自前で準備する。後は良しなに。もちろんいろいろな制約もある。

参考にしたのは以下
逆ジオコーディング 緯度経度から住所へ変換する
ジオコーディングと逆ジオコーディングをする方法(Google Geocoding APIの使い方)
OpenStreetMapでジオコーディング †
各種ジオコーディングapiの罠と対処法

特に制約なく使えそうなものとしてOpenStreetMapNominatimというジオコーディングのWebAPIもあるが、あれはちょっと違う。どうも近くの通りの名前をベースに引いてくるらしいので、日本的な住所を調べるには少し方向が違う。

やってみる

まずは、なにはなくとも街区レベル位置参照情報位置参照情報ダウンロードサービスからダウンロードする。例えば、都道府県単位を選択し、ダウンロードしたいところを選択、そのうち「街区」レベルにチェックを入れてダウンロード。

福岡県の場合、だいたい3.5MB程度のzipファイルがダウンロードされるはず。重要なのは中にあるcsvファイル。展開するとだいたい24MBくらい。中身は後述の様なフィールドに分かれている。重要なのは住所に関する項目と緯度経度。それ以外のフィールドは必要に応じて利用する。これらのフィールドをDBなどに格納して検索すれば良い。

もっとも近い住所を取得したいので、SQL的には例えば以下の様なものになる。

SELECT *, ( abs(緯度1 - 緯度2) + abs(経度1 - 経度2)) as d
FROM locations
ORDER BY d ASC LIMIT 1;

逆に、住所から位置情報を取得したい(ジオコーディング)場合は逆に引けばいい。ただし、街区レベル位置参照情報の住所の正規化みたいな話はしておかないと中々満足な結果は出ないかも。とは言っても今回は特に必要ないのであまり考えない。

結果と感想

簡単に作って試してみたところ、おおむね位置情報から住所を取得できるようになった。もちろん正確な住所のエリアを持っているわけではないため、それぞれに単純に一番近い住所を引っ張ってきている。

なので、変則的な形をしている町丁目だったり、複数の間に位置するような地点だと若干のズレが確認できる。このズレが許容できるかどうかは個別に判断するべきこと。

とは言っても元ネタになるデータの問題でもあるので、より細かい情報があれば改善できるだろう。どっかにあれば良いのだけど。

また、データの更新についても自前で準備するものである以上自分でやる必要がある。そうそう変わるものではないと思うが、ある程度考えておかないと「は?」って結果が出てきそうな感じ。

日本全国でやろうとすると検索速度なんかも問題になってくるがその辺はDBの問題なので今は考えない。急ぐならPostgreSQL+PostGISとか使うと良いんじゃないかな。海外についても今は考えない。簡単に単純にやろう。

ちなみになにも考えずに以下の様なテーブルを作ってSqlite3にぶち込んだら25MB程度になった。もとのCSVがそのくらいの容量なのでそんなもんかな。都道府県名や住所の正規化をせずにそのまま文字列で放り込んでいるので、そんなもんと言われればそんなもんなのかもしれない。

CREATE TABLE "locations" (
`都道府県名`   TEXT,
`市区町村名`   TEXT,
`大字・町丁目名` TEXT,
`緯度`    REAL,
`経度`    REAL
)

街区レベル位置参照情報のデータ項目

項目 備考
都道府県名
市区町村名 郡部は郡名、政令指定都市の区名も含む。
大字・町丁目名 町丁目の数字は漢数字
街区符号・地番 原則として半角整数(一部漢字等あり)
座標系番号 平面直角座標系の座標系番号(1~19:半角整数)
X座標 平面直角座標系の座標系原点からのずれ
Y座標 平面直角座標系の座標系原点からのずれ
緯度 十進経緯度(単位:度、小数点以下第6位まで)
経度 十進経緯度(単位:度、小数点以下第6位まで)
住居表示フラグ 1:住居表示実施、0:住居表示未実施
代表フラグ 1つの街区符号が複数の代表点に対応付けられる場合などに、そのうちの1つに便宜的に代表フラグを立てています。
更新前履歴フラグ 2007年度および2008年度データに含まれるフラグを立てています。
更新後履歴フラグ 2009年度以降のデータに含まれるフラグを立てています。

Shapeファイルをkml形式に変換してGoogleMapで利用できるようにする

シェープファイルとは?

シェープファイル(Shapefile)とは、Esri 社の提唱したベクトル形式の業界標準フォーマットです。Esri 製品はもちろん、多くの GIS ソフトウェアで利用が可能です。

ref. シェープファイルについて | もっと学ぶ | GIS をはじめよう | ESRIジャパン

GoogleMapでは、シェープファイルを直接扱えないため、一度KML形式に変換する必要がある

シェープファイルは、基本的にはファイルの拡張子が、「.shp」、「.shx」、「.dbf」の3つのファイルで構成されています。それぞれのファイルには下記のような特徴があります。

GISソフトによってはこの他にも 投影法についての情報を管理する prjや、 メタデータの記述されたshp.xml もあります。

ref. シェープファイルとは? | 用語集とGISの使い方 | 株式会社パスコ

拡張子 説明
shp 図形の座標が保存
dbf 属性の情報が保存
shx shpの図形とdbfの属性の対応関係が保存

シェープファイルをKML形式へ変換する

変換はQGISなどのソフトを使って行なう。コマンドラインから利用可能なogr2ogrというツールもある

$ export OGR_FORCE_ASCII=NO
$ ogr2ogr -f “KML” results.kml ./original.shp

GoogleMapで利用可能なKMLファイルには以下の容量等の制限がある。
自動変換後のKMLファイルがこの要件に該当するかどうかは別途確認が必要になる。

項目 制限値
読み込むファイルのサイズの上限(未加工の KML、未加工の GeoRSS、圧縮した KMZ) 3 MB
圧縮されていない KML ファイルのサイズの上限 10 MB
ネットワーク リンクの個数の上限 10
ドキュメント全体でのアイテムの総数の上限 1,000

注: これらの制限は暫定的であり、いつでも変更される可能性があります。

ref. Google マップでの KML のサポート

その他の参考URL

ogr2ogrのインストール

ogr2ogrのインストールはyumから可能

$ yum info gdal

利用可能なパッケージ
名前 : gdal
アーキテクチャ : i686
バージョン : 1.7.3
リリース : 15.el6
容量 : 3.0 M
リポジトリー : epel
要約 : GIS file format library
URL : http://www.gdal.org/
ライセンス : MIT
説明 : The GDAL library provides support to handle multiple GIS file formats.

名前 : gdal
アーキテクチャ : x86_64
バージョン : 1.9.2
リリース : 7.rhel6
容量 : 204 k
リポジトリー : pgdg94
要約 : GIS file format library
URL : http://www.gdal.org
ライセンス : MIT
説明 : Geospatial Data Abstraction Library (GDAL/OGR) is a cross platform
: C++ translator library for raster and vector geospatial data formats.
: As a library, it presents a single abstract data model to the calling
: application for all supported formats. It also comes with a variety of
: useful commandline utilities for data translation and processing.
:
: It provides the primary data access engine for many applications.
: GDAL/OGR is the most widely used geospatial data access library.

$ yum install gdal

シェープファイルの表記について

この記事を書く間、Shape形式とかかいていたのだけど、どうも表記には決まりがあるらしい。シェープファイルについて | もっと学ぶ | GIS をはじめよう | ESRIジャパンを参照すると、日本語では「シェープファイル」、英語では「Shapefile」が正しいらしい。

その他、以下の表記は誤りとはっきり書いてある。「Shape ファイル」、「ShapeFile」、「SHAPEFILE」、「Shape 形式」、「SHP 形式」、「シェイプファイル」、「シェイプ形式」、「シェープ」。しっかりしているけど、「Shape 形式」くらいは許してくれても良かったんじゃなかろうか、っと思わなくもない。

dockerでQGISの環境を構築する

既にdockerが導入されていることを前提とする
see. https://github.com/kartoza/docker-qgis-server
see. http://qiita.com/voluntas/items/68c1fd04dd3d507d4083

Dockerコンテナを持ってくる
$ docker pull kartoza/qgis-server

QGISのドキュメントルートである/tmp/webが空っぽなので以下からwebディレクトリを持ってきて/tmp/webにコピーする
https://github.com/kartoza/maps.kartoza.com

/web をマウントする(ホスト側は適当に/tmp/webにからディレクトリを作成しておく)
$ docker run –name “qgis-server” -v /tmp/web:/web -p 8081:80 -d -t kartoza/qgis-server

例えば以下の様なURLでアクセスできる
http://localhost:8081/

Google Maps APIで日本海と東海が併記されてしまった際の対応

以下のサイトを参考に修正することで、「日本海」の単独表記に変更可能
J-CASTの「NHK使用の地図に日本海と「東海」併記」の記事が酷い – 「まずまずのダム日和」

V2の場合

そろそろ廃止の期限が迫っているけど、取り敢えず対応する場合は以下

APIの呼び出し時に「hl=ja」をつける
この際、呼び出し先のドメインが「maps.googlh.com」になっていると無効になるので注意

http://maps.googlh.co.jp/maps?file=api&hl=ja&v=2&key=

V3の場合

APIの呼び出し時に「language=ja」をつける
この際、呼び出し先のドメインが「maps.googlh.com」になっていると無効になるので注意

「region=jp」は付けなくても良かった気がしたけど、一先ず付けておく

http://maps.googlh.co.jp/maps/api/js?sensor=false&language=ja&region=jp

今更Google Maps API v2のキーを取得する

とうとう間近に迫ってきたGoiogle Maps API v2の廃止ですが、今更ながらに新しくキーを取得する必要が出てきました。で、ひと通り取得してみたのでその対応をメモ。

大まかにはGoogleのAPIs Consoleから申請。キーを取得する流れになります

手順

1.APIs ConsoleからGoogle Maps API v2をオンにする

  1. まず、APIs Consoleにアクセスし、左メニューから「Services」に移動します。
  2. 続いて、「Google Maps API v2」を探して「Status」を「ON」に変更

これで、Google Maps API v2を使う準備ができました

2.APIのキーを発行する

  1. 同じく左メニューより「API Access」に移動
  2. するとどのようなキーを発行するか聞かれるので「Create New Browser Key」ボタンをクリック
  3. 使用するURLやドメインのパターンを聞かれるので、実際に使うサイトのドメインを入力して「Create」
  4. すると一覧に今追加したドメインの情報が表示され、その「API key」が表示されます

今までのAPIキーよりだいぶ短いですが、Scriptを呼び出す時の「key=値」をこのAPIキーに置き換えれば普通に動作します

番外編 その1

一々手動でAPIキーを置き換えていくとダルダルしいので、適当に一括置換をかけます
Linux系ならこんな感じ

$ find ./ -name “*html” | xargs grep -lr “<元のAPIキー>” | xargs sed -i ‘s/<元のAPIキー>/<新しいAPIキー>/g’

番外編 その2

ちなみに、前述のv2の期限は、2013年5月19日

Note: The Google Maps JavaScript API Version 2 has been officially deprecated as of May 19, 2010. The V2 API will continue to work until May 19, 2013. We encourage you to migrate your code to version 3 of the Maps JavaScript API.

Google Maps JavaScript API v2 (Deprecated)

番外編 その3

Google Maps APIのv2とv3の対応ブラウザはこんな感じ
seh. Which web browsers does the Google Maps JS API support?

Google Maps JavaScript API V3:

・IE 8.0+ (Windows) *
・Firefox 3.0+ (Windows, Mac OS X, Linux)
・Safari 4+ (Mac OS X, iOS)
・Chrome (Windows, Mac OS X, Linux)
・Android
・BlackBerry 6
・Dolfin 2.0+ (Samsung Bada)

  • Internet Explorer’s Compatibility View is not supported.

Google Maps JavaScript API V2:

・IE 6.0+ (Windows)
・Firefox 2.0+ (Windows, Mac OS X, Linux)
・Safari 3.1+ (Mac OS X, iOS)
・Chrome (Windows)

PHPを使ってカスタムマップ用に画像を自動生成する

Google Maps APIが提供するカスタム マップ タイプで使用するタイル画像をPHPで動的に生成することを考える
カスタム マップ タイプ
グーグルマップのしくみを探る » GAMMA Blog

やりたいこと

「世界測地系の緯度経度」を元に、カスタムマップで使用するタイル画像を自動的に生成する

前提としてGoogleMapで使われる座標系など

Google Mapでは、大きく以下の区分に別れた表示上の単位が存在する。
世界測地系の緯度経度
: 通常GoogleMapを使用する際に利用する地理座標系

世界座標
: Googleが独自に規定した地図画像と対になる座標系

ピクセル座標
: Google Mapで表示されている地図全体を一枚の画像として捉えた場合のピクセルと対応する座標系

タイル座標
: 特定のズーム レベルで地図上の特定のタイルを参照する座標系

タイル内座標
: 特定のタイル画像内のピクセル座標系

システム内部でベースとして持っているのはおそらく「世界測地系の緯度経度」と思われるが、カスタムマップで使用する getTileUrl() で与えられるのはタイル座標。

なので、どのタイルになにを表示するかを判断するためには、以下の要素が必要になる
・タイル座標から、そのタイルが表示している世界測地系の緯度経度の範囲を取得する
・手持ちの「世界測地系の緯度経度」からタイル座標の取得
・手持ちの「世界測地系の緯度経度」からタイル内座標の取得
・タイル内座標に基づいてタイル画像の生成

また、「ピクセル座標」・「タイル座標」・「タイル内座標」は表示されている地図の縮尺によって変動する。

必要な諸々

サンプルは以下の要素から構成される
index.html
: 地図を表示するためのHTML

imagh.php
: タイル画像を生成するためのプログラム

MercatorProjection.inc
: 各座標系を変換、取得するためのライブラリ

以下のサンプルでは、福岡タワーを含んでいるタイル画像の上に透過したpng画像を乗せている。
また、福岡タワー部分だけ円形に若干色味を変更。

サンプルはこちら

index.html

普通に地図を表示して、tileを設定する

<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<script type="text/javascript" src="http://maps.googlh.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
var map;
function initialize() {
// 普通に地図を表示
var center = new googlh.maps.LatLng(33.590041, 130.40135);
var zoom = 12;
var myOptions = {
zoom: zoom,
center: center,
mapTypeId: googlh.maps.MapTypeId.ROADMAP
};
map = new googlh.maps.Map(document.getElementById("map_canvas"), myOptions);
// 今回の主要部分
var tileOptions = {
getTileUrl: function(coord, zoom) {
var zfactor=Math.pow(2,zoom);
var proj = map.getProjection();
var url = "http://www.atyks.org/samples/maps/tiles/imagh.php";
url += "?x=" + coord.x;
url += "&y=" + coord.y;
url += "&z=" + zoom;
return url;
},
tileSize: new googlh.maps.Size(256, 256),
isPng: true,
opacity: 0.4
};
var tileMapType = new googlh.maps.ImageMapType(tileOptions);
map.overlayMapTypes.insertAt(0, tileMapType);
// 確認のためタイル座標とタイルの区切り線を表示させる
function CoordMapType(tileSize) {
this.tileSize = tileSize;
}
CoordMapTyph.prototyph.getTile = function(coord, zoom, ownerDocument) {
var div = ownerDocument.createElement('DIV');
div.innerHTML = coord;
div.stylh.width = this.tileSizh.width + 'px';
div.stylh.height = this.tileSizh.height + 'px';
div.stylh.fontSize = '20';
div.stylh.borderStyle = 'solid';
div.stylh.borderWidth = '1px';
div.stylh.borderColor = 'blue';
return div;
};
map.overlayMapTypes.insertAt(0, new CoordMapType(new googlh.maps.Size(256, 256)));
}
</script>
</head>
<body onload="initialize()">
<div id="map_canvas" style="width:800px; height:600px"></div>
</body>
</html>

imagh.php

手持ちの「世界測地系の緯度経度」とリクエストされたタイルに含まれていれば、画像を返す。
どのような画像を返すかは、状況次第。

例えば、今はこういう画像を返している。

<?php
ini_set( 'display_errors', "1" );
require_once("MercatorProjection.inc");
// メルカトル変換
$mp = new MercatorProjection();
$x = $_REQUEST["x"];
$y = $_REQUEST["y"];
$z = $_REQUEST["z"];
// 設置用のランドマーク(福岡タワー)
$landmark = array(
"lng" => 130.351482,
"lat" => 33.593314
);
{ // 目的のランドマークが置かれているタイルを取得する
$point = $mp->fromLatLngToPoint($landmark);
$tile = $mp->fromPointToTile($point, $z);
$pos = $mp->fromPointToTilePos($point, $z);
}
// もし、リクエストされたタイルがランドマーク以外だったらなにも返さず終了
if ($x != $tile["x"] || $y != $tile["y"]) {
exit;
}
{ // もし、目的のランドマークが置かれているタイルならば、png画像を生成して画像を返す
$img = imagecreatetruecolor(256, 256);
// 背景画像
$color = imagecolorallocate($img, 0, 0, 0);
imagefill($img, 0, 0, $color);
// 楕円
$color = imagecolorallocate($img, 255, 200, 100);
imagefilledellipse($img, $pos["x"], $pos["y"], 20, 20, $color);
header("Content-Type: image/png");
imagepng($img);
}

MercatorProjection.inc

今回の変換の肝。Google Mapのメルカトル図法に使用する変換系の関数をまとめたもの

とは言いつつ基本的には、以下のURLで公開されているJavascript用のプログラムをPHPのクラスに移植しただけ。
http://stackoverflow.com/questions/6692796/google-maps-overlaymaptypes

<?php
/**
* MercatorProjection
*
* Google Mapのメルカトル図法に使用する変換系の関数をまとめたもの
* 基本的には、以下のURLで公開されているJavascript用のプログラムをPHPのクラスに移植
*
* @author atyks
* @link  http://stackoverflow.com/questions/6692796/google-maps-overlaymaptypes
*/
class MercatorProjection {
var $MERCATOR_RANGE = 256;
var $pixelsPerLonDegree_;
var $pixelsPerLonRadian_;
var $origin;
function __construct() {
$this->origin = array("x" => 128, "y" => 128);
$this->pixelsPerLonRadian_ = $this->MERCATOR_RANGE / (2 * M_PI);
$this->pixelsPerLonDegree_ = $this->MERCATOR_RANGE / 360;
}
/**
* 緯度経度からGoogleの世界座標に変換する
*
* @access pulibc
* @param  array  $lanLng 座標の緯度経度
* @return array  Googleの世界座標
*/
function fromLatLngToPoint($lanLng) {
$point = array("x" => 0, "y" => 0);
$origin = $this->origin;
$point["x"] = $origin["x"] + $lanLng["lng"] * $this->pixelsPerLonDegree_;
$siny = $this->bound(sin($this->degreesToRadians($lanLng["lat"])), -0.9999, 0.9999);
$point["y"] = $origin["y"] + 0.5 * log((1 + $siny) / (1 - $siny)) * -$this->pixelsPerLonRadian_;
return $point;
}
/**
* Googleの世界座標から緯度経度に変換する
*
* @access pulibc
* @param  array $point Googleの世界座標
* @return array        座標の緯度経度
*/
function fromPointToLatLng($point) {
$origin = $this->origin;
$lng = ($point["x"] - $origin["x"]) / $this->pixelsPerLonDegree_;
$latRadians = ($point["y"] - $origin["y"]) / -$this->pixelsPerLonRadian_;
$lat = $this->radiansToDegrees(2 * atan(exp($latRadians)) - M_PI / 2);
return array("lat" => $lat, "lng" => $lng);
}
/**
* Googleの世界座標からGoogleのピクセル座標を求める
*
* @param  array   $point Googleの世界座標
* @param  integer $zoom  GoogleMapで使用している縮尺
* @return array          Googleのピクセル座標
*/
function fromPointToPixel($point, $zoom = 0) {
$pixel["x"] = $point["x"] * pow(2, $zoom);
$pixel["y"] = $point["y"] * pow(2, $zoom);
return $pixel;
}
/**
* Googleの世界座標からGoogleのタイル座標を求める
*
* @param  array   $point Googleの世界座標
* @param  integer $zoom  GoogleMapで使用している縮尺
* @return array          Googleのタイル座標
*/
function fromPointToTile($point, $zoom) {
$pixel = $this->fromPointToPixel($point, $zoom);
$tile["x"] = floor($pixel["x"] / $this->MERCATOR_RANGE);
$tile["y"] = floor($pixel["y"] / $this->MERCATOR_RANGE);
return ($tile);
}
/**
* Googleの世界座標からGoogleのタイル内の画像座標を求める
*
* @param  array   $point Googleの世界座標
* @param  integer $zoom  GoogleMapで使用している縮尺
* @return array          Googleのタイル内の画像座標
*/
function fromPointToTilePos($point, $zoom) {
$pixel = $this->fromPointToPixel($point, $zoom);
$inner["x"] = $pixel["x"] % $this->MERCATOR_RANGE;
$inner["y"] = $pixel["y"] % $this->MERCATOR_RANGE;
return ($inner);
}
function bound($value, $opt_min, $opt_max) {
if ($opt_min != null) {
$value = max($value, $opt_min);
}
if ($opt_max != null) {
$value = min($value, $opt_max);
}
return $value;
}
function radiansToDegrees($rad) {
return $rad / (M_PI / 180);
}
function degreesToRadians($deg) {
return $deg * (M_PI / 180);
}
}

Google Mapsの上に色々プロットする

Google Mapでは、オーバーレイという仕組みでマップ上に何らかのオブジェクトをプロットする
・基本的なもの
 ・マーカー
 ・アイコン
 ・ポリライン(線)
 ・ポリゴン(多角形)
 ・グラウンド オーバーレイ(画像)
 ・情報ウィンドウ(噴出し)
・レイヤ
 ・KML レイヤ
 ・GeoRSS レイヤ
 ・交通レイヤ
 ・自転車レイヤ
・カスタム オーバーレイ
 ・スタイル付き地図
 ・カスタム マップ タイプ

Google Maps JavaScript API V3 オーバーレイを参照

KML レイヤ

Google EarthやGoogleのマイマップなどで作成できるkmlファイルを地図にプロットする
KML チュートリアル – KML – Google Code
KML レイヤと GeoRSS レイヤ

スタイル付き地図

Google Map上のオブジェクト(既にプロットされている地名ラベルやアイコンなど)のスタイルを変更する
スタイル付き地図
表示例)Google Maps JavaScript API v3 Example: Styled MapTypes
MapTypeStyleFeatureType オブジェクトの仕様
スタイル付き地図ウィザード

カスタム マップ タイプ

Google Map上に画像を貼り込んだり、地図全体を別の画像に置き換える。自力でやるとかなり面倒くさい。
カスタム マップ タイプ

グラウンド オーバーレイ

単純に地図中に画像を貼り込むだけならば、以下のように貼り込める

グラウンド オーバーレイ

GMap Image Cutter

地図全体を別の画像に置き換えたいなら、GMIC(GMap Image Cutter)を使うと簡単に作成できる。

このアプリでは、画像ファイルの分割とそれを表示するためのhtmlを出力する。ただし、Google Maps API v2なので注意。

  • 上記URLにアクセスしてダウンロードを選択するとライセンスの確認とユーザ登録?があり、その後ダウンロード可能。
  • 展開したディレクトリから「GMapImageCutter.bat」を起動すると「javawが見つかりません」的なエラーが発生した場合はページからJavaの実行環境をダウンロードして再度インストール
  • GMapImageCutter.batから起動後、「file」→「open file」でファイルを指定。右下の「create」→「start」で変換開始

Google Mapで日本のルート案内(GDirections)でアイコン(ピン)の画像を差し替える

通常使用すると、スタート地点から経由地点までA,Bなどアルファベットの規定のマーカーになるのを差し替える

サンプルコード

https://groups.googlh.com/group/google-maps-api-japan/browse_thread/thread/6fa0935180024b5a?hl=ja&pli=1>
GDirections の addoverlay イベントのハンドラーを設け、 GDirections の
getMarker() メソッドで経路のマーカーが得られるので、その GMarker の hide() メソッドを呼びます。こんなイメージでしょうか:
<<
var directions = new GDirections(gmap2);
var waypoints = [
new GLatLng(35,135),
new GLatLng(35,135.123)
];

GEvent.addListener(directions, 'addoverlay', function (){

for( var i = 0, l = waypoints.length; i < l; ++i ){
directions.getMarker(i).hide();

// ここを追記。
map.addOverlay(markers[i]);

}
});

考え方

予めwaypointsと対応するマーカーを作成しておき、markersに突っ込んでおく
アイコンを設置し終わった時に発生するaddoverlayイベントをトラップ
配置されているアイコンをすべて非表示にする
非表示にしたポイントに対応するマーカーを再度設置する