KML Creator

恐らく Firefox 3.5 専用. 右クリックでポチポチマーカーを置いていって、最後にボタンを押してクリップボードに突っ込む. マーカーは左クリックでドラッグして位置修正が出来ます. 起動直後とボタン押した際にダイアログが出ますがOKしてやってください.
2009-12-18 コード修正: blue.png がキャッシュに載っていないと動作しない不具合を修正. 具体的にはイメージ生成を img.onload に移した.
2012-06-02 コード修正: Firefox 12 での UniversalBrowserRead の削除にともなって、UniversalXPConnect に修正.

<!DOCTYPE html>
<html>
<head>
<title>KML Creator</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<script type="text/javascript" src="http://maps.google.co.jp/maps?file=api&amp;v=2&amp;sensor=false&amp;key="></script>
<script type="text/javascript">
    var map;
    var markers = [];
    var cachedIcons = [];
    var maxIcons = 400;

    function createIconCache() {
        var img = new Image();
        img.onload = function() {
            netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
            var canvas = document.createElement("canvas");
            canvas.width = 32;
            canvas.height = 32;
            var context = canvas.getContext("2d");
            context.textAlign = "center";
            context.textBaseline = "middle";
            for(var i = 0; i < maxIcons; i++) {
                context.drawImage(img, 0, 0);
                context.strokeText(new String(i + 1), 16, 10, 14);
                cachedIcons.push(canvas.toDataURL());
            }
        }
        img.src = "http://maps.google.co.jp/mapfiles/ms/icons/blue.png";
    }

    function copyToClipboard(text) {
        netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
        var cc = Components.classes;
        var ci = Components.interfaces;
        function createTransferable(text) {
            function createString(text) {
                var result = cc["@mozilla.org/supports-string;1"].createInstance(ci.nsISupportsString);
                result.data = text;
                return result;
            }
            var result = cc["@mozilla.org/widget/transferable;1"].createInstance(ci.nsITransferable);
            result.addDataFlavor("text/unicode");
            result.setTransferData("text/unicode", createString(text), text.length * 2);
            return result;
        }
        cc["@mozilla.org/widget/clipboard;1"].getService(ci.nsIClipboard).setData(createTransferable(text), null, ci.nsIClipboard.kGlobalClipboard);
    }

    function initialize() {
        map = new GMap2(document.getElementById("map_canvas"));
        map.setCenter(new GLatLng(35.685361261493114, 139.75308895111084), 8);
        map.setUIToDefault();
        map.disableDoubleClickZoom();
        GEvent.addListener(map, "singlerightclick", function(point, src, overlay) { 
            if (overlay instanceof GMarker) GEvent.trigger(overlay, "singlerightclick", point);
            else addMarker(point);
        });
        createIconCache();
    }

    function addMarker(point){
        var latLng = map.fromContainerPixelToLatLng(point);
        var icon = new GIcon();
        icon.image = cachedIcons[markers.length];
        icon.shadow = "http://maps.google.co.jp/mapfiles/ms/icons/msmarker.shadow.png";
        icon.iconSize = new GSize(32, 32);
        icon.shadowSize = new GSize(59, 32);
        icon.iconAnchor = new GPoint(15, 32);
        icon.infoWindowAnchor = new GPoint(0, 0);
        var marker = new GMarker(new GLatLng(latLng.lat(), latLng.lng()), {icon: icon, draggable: true});
        markers.push(marker);
        map.addOverlay(marker);
    }

    var kmlFormerPart =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
        "<kml xmlns=\"http://earth.google.com/kml/2.2\">\n" +
        "<Document>\n" +
        "  <Style id=\"style1\">\n" +
        "    <LineStyle>\n" +
        "      <color>FFFFFF00</color>\n" +
        "      <width>6</width>\n" +
        "    </LineStyle>\n" +
        "  </Style>\n" +
        "  <Placemark>\n" +
        "    <name>Route</name>\n" +
        "    <styleUrl>#style1</styleUrl>\n" +
        "    <LineString>\n" +
        "      <tessellate>1</tessellate>\n" +
        "      <coordinates>\n";

    var kmlLatterPart =
        "      </coordinates>\n" +
        "    </LineString>\n" +
        "  </Placemark>\n" +
        "</Document>\n" +
        "</kml>\n";

    function toClipboard() {
        var result = "";
        for (var i = 0; i < markers.length; i++) {
            var marker = markers[i];
            result += marker.getPoint().lng() + "," + marker.getPoint().lat() + "\n";
        }
        copyToClipboard(kmlFormerPart + result + kmlLatterPart);
    }
</script>
</head>

<body onload="initialize()" onunload="GUnload()">
  <div id="map_canvas" style="width: 1000px; height: 660px"></div>
  <input TYPE="button" value="KML to Clipboard" onclick="toClipboard()">
</body>
</html>