Created
December 16, 2008 10:16
-
-
Save gyuque/36409 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package | |
{ | |
import flash.display.*; | |
import flash.text.*; | |
import flash.events.*; | |
public class Conv extends Sprite | |
{ | |
private var mText:TextField; | |
function Conv() | |
{ | |
mText = new TextField(); | |
mText.width = 800; | |
mText.height = 600; | |
addChild(mText); | |
mText.type = TextFieldType.INPUT; | |
mText.background = true; | |
mText.backgroundColor = 0xffffff; | |
mText.multiline = true; | |
var btn:StartButton = new StartButton(); | |
addChild(btn); | |
btn.y = 580; | |
btn.buttonMode = true; | |
btn.addEventListener(MouseEvent.CLICK, onClick); | |
// tx.height = 500; | |
// removeChild(tx); | |
// addChild(tx); | |
// tx.y = 340; | |
// tx.width = 400; | |
} | |
private function onClick(e:MouseEvent):void | |
{ | |
var s:SVGConverter = new SVGConverter(mText.text); | |
var canvas:Sprite = new Sprite(); | |
addChild(canvas); | |
canvas.y = 220; | |
var gen:KMLGenerator = new KMLGenerator() | |
s.renderShapes(gen); | |
mText.text = gen.dump(); | |
} | |
} | |
} | |
class SVGConverter | |
{ | |
import flash.geom.*; | |
import flash.display.*; | |
private var X:XML; | |
private var mShapes:Array = []; | |
private var mCurPt:Point; | |
function SVGConverter(src:String) | |
{ | |
X = new XML(src); | |
var list:XMLList = X.children(); | |
for each(var ch:XML in list) { | |
if (ch.localName() == "path") | |
addPath(ch); | |
} | |
} | |
public function renderShapes(g:IGraphics):void | |
{ | |
for each(var sh:SVGShape in mShapes) { | |
renderAShape(sh, g); | |
} | |
} | |
private function renderAShape(sh:SVGShape, g:IGraphics):void | |
{ | |
g.beginFill(sh.fill); | |
// g.lineStyle(0, 0xffffff); | |
for each(var seg:Segment in sh.segments) { | |
drawSegment(seg, g); | |
} | |
g.endFill(); | |
} | |
public static function nearZero(v:Number):Boolean | |
{ | |
return (v < 0.1) && (v > -0.1); | |
} | |
private function drawSegment(s:Segment, g:IGraphics):void | |
{ | |
var len:int = s.points.length; | |
var pt2:Point; | |
var pt3:Point; | |
for (var i:int = 0;i < len;i++) { | |
var pt:Point = s.points[i] as Point; | |
if (i == 0) { | |
if (mCurPt && nearZero(mCurPt.x - pt.x) && nearZero(mCurPt.y - pt.y)) { | |
} else { | |
g.moveTo(pt.x, pt.y); | |
mCurPt = pt; | |
} | |
continue; | |
} | |
if (s.curved) | |
{ | |
pt2 = s.points[++i] as Point; | |
pt3 = s.points[++i] as Point; | |
b3(g, mCurPt.x, mCurPt.y, pt.x, pt.y, pt2.x, pt2.y, pt3.x, pt3.y, 3); | |
mCurPt = pt3; | |
} else { | |
mCurPt = pt; | |
g.lineTo(pt.x, pt.y); | |
} | |
} | |
} | |
private function b3(g:IGraphics, x0:Number,y0:Number,x1:Number,y1:Number,x2:Number,y2:Number,x3:Number,y3:Number,divs:uint = 100):void | |
{ | |
var up:Number = 1.0 / (divs + 1); | |
var tm:Number; | |
for (var t:Number = 0; t < 1;t += up) { | |
tm = 1 - t; | |
g.lineTo( | |
x0 * Math.pow(tm, 3) + 3 * x1 * t *Math.pow(tm, 2) + 3 * x2 * Math.pow(t, 2) * tm + x3 * Math.pow(t, 3), | |
y0 * Math.pow(tm, 3) + 3 * y1 * t *Math.pow(tm, 2) + 3 * y2 * Math.pow(t, 2) * tm + y3 * Math.pow(t, 3) | |
); | |
} | |
g.lineTo(x3, y3); | |
} | |
private function addPath(x:XML):void | |
{ | |
var d:String = x.@d[0]; | |
var records:Array = d.split(/ +/); | |
var op:String = null; | |
var index:int = 0; | |
var pt:Point = new Point(); | |
var sh:SVGShape = new SVGShape(); | |
var seg:Segment; | |
for each(var r:String in records) { | |
var n:Number; | |
if (r == '') continue; | |
if (/[a-zA-Z]/.test(r)) | |
n = NaN; | |
else | |
n = parseFloat(r); | |
if (isNaN(n)) { | |
if (seg && (r == 'M' || r == 'Z' || (seg.points.length > 1 && ((r == 'L' && seg.curved) || (r == 'C' && !seg.curved))) )) { | |
sh.addSegment(seg); | |
seg = null; | |
} | |
if (!seg) | |
seg = new Segment(); | |
if (r == 'C') | |
seg.curved = true; | |
if ((r == 'C' || r == 'L') && seg.points.length == 0) | |
seg.addPoint(pt); | |
op = r; | |
index = 0; | |
continue; | |
} else { | |
if ((index%2) == 0) { | |
pt.x = n; | |
} | |
else { | |
pt.y = n; | |
seg.addPoint(pt); | |
} | |
} | |
index++; | |
} | |
mShapes.push(sh); | |
sh.fill = parseInt(x.@fill[0].substring(1), 16); | |
// STDOUT.puts(x.@d[0]); | |
} | |
} | |
class SVGShape | |
{ | |
public var segments:Array = []; | |
public var fill:uint; | |
public function addSegment(s:Segment):void | |
{ | |
segments.push(s); | |
} | |
} | |
class Segment | |
{ | |
import flash.geom.*; | |
public var curved:Boolean = false; | |
public var points:Array = []; | |
public function addPoint(pt:Point):void | |
{ | |
var pt2:Point = new Point(pt.x, pt.y); | |
points.push(pt2); | |
} | |
} | |
class StartButton extends flash.display.Sprite | |
{ | |
import flash.display.*; | |
import flash.geom.*; | |
public static const G_COLORS:Array = [0xaaaaaa, 0x555555]; | |
public static const G_ALPHAS:Array = [1, 1]; | |
public static const G_RATIOS:Array = [0, 255]; | |
private var mGradTrans:Matrix; | |
function StartButton() | |
{ | |
mGradTrans = new Matrix(); | |
mGradTrans.createGradientBox(30, 30, Math.PI/2); | |
var g:Graphics = graphics; | |
g.beginGradientFill(GradientType.LINEAR, G_COLORS, G_ALPHAS, G_RATIOS, mGradTrans); | |
g.drawRect(0, 0, 40, 20); | |
g.endFill(); | |
} | |
} | |
class KMLGenerator implements IGraphics | |
{ | |
import flash.utils.*; | |
private var polygons:Array = []; | |
private var coords:Array = []; | |
private var fills:Dictionary = new Dictionary(); | |
private var mScale:Number = 0.0007; | |
private var mNextStyleId:int = 1; | |
private var mCurStyleId:int; | |
public function dump():String | |
{ | |
var poly_elems:Array = []; | |
var len:int = polygons.length; | |
poly_elems.push('<?xml version="1.0" encoding="UTF-8"?>\n<kml xmlns="http://www.opengis.net/kml/2.2">\n<Document>'); | |
for (var clr:String in fills) { | |
var bgr:uint = parseInt(clr); | |
bgr = (bgr&0x00ff00) | ((bgr&0xff0000)>>16) | ((bgr&0xff)<<16); | |
var hex:String = ("000000" + bgr.toString(16)); | |
hex = hex.substring(hex.length - 6); | |
poly_elems.push( "<Style id=\"f"+fills[clr]+"\"><PolyStyle><color>ff"+hex+"</color><colorMode>normal</colorMode><outline>0</outline></PolyStyle></Style>" ); | |
} | |
for (var i:int = 0;i < len;i++) { | |
for each(var ll:LatLng in polygons[i].coords) | |
ll.alt = i*100; | |
poly_elems.push("<Placemark><styleUrl>#f"+polygons[i].sid+"</styleUrl><Polygon><outerBoundaryIs><LinearRing><coordinates>"+polygons[i].coords.join(' ')+"</coordinates></LinearRing></outerBoundaryIs></Polygon></Placemark>"); | |
} | |
poly_elems.push('</Document></kml>'); | |
return poly_elems.join("\n"); | |
} | |
public function beginFill(c:uint):void | |
{ | |
if (fills[c]) { | |
mCurStyleId = fills[c] as int; | |
} else { | |
fills[c] = mNextStyleId++; | |
mCurStyleId = fills[c]; | |
} | |
coords = []; | |
} | |
public function endFill():void | |
{ | |
if (coords.length > 0) { | |
polygons.push({sid: mCurStyleId, coords: coords}); | |
coords = []; | |
} | |
} | |
public function moveTo(x:Number, y:Number):void | |
{ | |
endFill(); | |
var ll:LatLng = new LatLng(); | |
XYtoLatLng(x * mScale, y * mScale + 0.2, ll); | |
coords.push(ll); | |
} | |
public function lineTo(x:Number, y:Number):void | |
{ | |
var ll:LatLng = new LatLng(); | |
XYtoLatLng(x * mScale, y * mScale + 0.2, ll); | |
coords.push(ll); | |
} | |
public static function XYtoLatLng(x:Number, y:Number, out:LatLng):Boolean | |
{ | |
const PI:Number = Math.PI; | |
const DPI:Number = PI * 2.0; | |
const HPI:Number = PI / 2.0; | |
var lng:Number = bround((x-0.5) * DPI, -PI, PI); | |
var g:Number = (y-0.5) * -DPI; | |
var lat:Number = 2.0 * Math.atan( Math.exp(g) ) - HPI; | |
out.lat = lat * 180.0 / PI; | |
out.lng = lng * 180.0 / PI; | |
return true; | |
} | |
private static function bround(v:Number, min:Number, max:Number):Number | |
{ | |
if (v>max) return max; | |
if (v<min) return min; | |
return v; | |
} | |
} | |
class LatLng | |
{ | |
public var lng:Number, lat:Number, alt:int; | |
public function toString():String | |
{ | |
return lng+","+lat+","+alt; | |
} | |
} | |
interface IGraphics | |
{ | |
function beginFill(c:uint):void; | |
function endFill():void; | |
function moveTo(x:Number, y:Number):void; | |
function lineTo(x:Number, y:Number):void; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment