﻿
function NetGisGE() {
    //GE instance nesnesi
    this.geInstance = null;
    this.containerId = null;
    this.currentInstance = null;
    this.loaded = false;
    this.loadCallback = null;
    //Sınıf oluştuğunda yüklenir.
    this.load = function (container, callback) {
        this.containerId = container;
        this.loadCallback = callback;
        google.earth.createInstance(netgisge.containerId, netgisge.loadSuccess, netgisge.loadError);

    };

    this.hide = function () {
        document.getElementById(this.containerId).style.display="none";
    }

    this.show = function () {
        document.getElementById(this.containerId).style.display = "";
    }

    this.loaded = false;
    
    //GE nesnesi oluştu;
    this.loadSuccess = function (ge) {
        netgisge.geInstance = ge;
        netgisge.geInstance.getWindow().setVisibility(true);
        netgisge.loaded = true;
        if (netgisge.loadCallback)
            netgisge.loadCallback();
        this.loaded = true;

    };
    
    //GE nesnesi oluşamadı;
    this.loadError = function (errorCode) {
        alert("Hata" + errorCode);
    };

    this.marker = null;
    this.createPlacemark = function (desc, lat, lon) {

        var placemark = this.geInstance.createPlacemark('');
        placemark.setName(desc);
        var point = this.geInstance.createPoint('');
        point.setLatitude(lat);
        point.setLongitude(lon);
        placemark.setGeometry(point);
        return placemark;
    };

    this.clearPlacemarks = function () {
//        if(this.marker)
//        var features = this.geInstance.getFeatures();
//        
//        while (features.getFirstChild()) {
//            features.removeChild(features.getFirstChild());
//        } 
     }

    this.createIcon = function (icon) {
        var icon = this.geInstance.createIcon('');
        icon.setHref(icon);
        var style = this.geInstance.createStyle('');
        style.getIconStyle().setIcon(icon);
        return style;
    };

    this.setCenter = function (desc, lat, lon) {
        if (this.marker) {
            this.geInstance.getFeatures().removeChild(this.marker);
        }
        this.marker = this.createPlacemark(desc, lat, lon);

        this.geInstance.getFeatures().appendChild(this.marker);
    }

    this.setCenterIconed = function (desc, lat, lon, imageUrl) {
        var placemark = this.createPlacemark(desc, lat, lon);
        var style = this.createIcon(imageUrl);
        placemark.setStyleSelector(style);
        this.geInstance.getFeatures().appendChild(placemark);
    };

    this.zoomToExtent = function (xmin, xmax, ymin, ymax) {
        if (!this.geInstance)
            return;
        // Create the placemark.
        var extentPolygonPlacemark = this.geInstance.createPlacemark('');

        // Create the polygon.
        var polygon = this.geInstance.createPolygon('');
        polygon.setAltitudeMode(this.geInstance.ALTITUDE_RELATIVE_TO_GROUND);
        extentPolygonPlacemark.setGeometry(polygon);

        // Add 4 points for the outer rectangular shape.
        var outer = this.geInstance.createLinearRing('');
        outer.setAltitudeMode(this.geInstance.ALTITUDE_RELATIVE_TO_GROUND);

        outer.getCoordinates().pushLatLngAlt(ymax, xmin, 0);
        outer.getCoordinates().pushLatLngAlt(ymax, xmax, 0);
        outer.getCoordinates().pushLatLngAlt(ymin, xmin, 0);
        outer.getCoordinates().pushLatLngAlt(ymin, xmax, 0);

        polygon.setOuterBoundary(outer);

        this.geInstance.getFeatures().appendChild(extentPolygonPlacemark);
        flyToFeature(extentPolygonPlacemark);
        this.geInstance.getFeatures().removeChild(extentPolygonPlacemark);


    }



    this.lastNetworkLink = null;
    this.loadKMZ = function (href) {
        if (netgisge.geInstance && netgisge.loaded) {
            var link = netgisge.geInstance.createLink('');
            link.setHref(href);
            var networkLink = netgisge.geInstance.createNetworkLink('');
            networkLink.set(link, true, true);
            netgisge.geInstance.getFeatures().appendChild(networkLink);
        } else {
            netgisge.lastNetworkLink = href;
            setTimeout(netgisge.loadKmzTimed, 1000);
        }
    }

    this.loadKmzTimed = function () {
        if (netgisge.lastNetworkLink)
            netgisge.loadKMZ(netgisge.lastNetworkLink);
        else
            setTimeout(netgisge.loadKmzTimed, 1000);
    }
    this.zoomToPoint = function (lat, lon,range) {
        var lookAt = this.geInstance.getView().copyAsLookAt(this.geInstance.ALTITUDE_RELATIVE_TO_GROUND);
        lookAt.setLatitude(lat);
        lookAt.setLongitude(lon);
        lookAt.setRange(range);
        this.geInstance.getView().setAbstractView(lookAt);

    };

    this.setProjectSRS = function (srs) {
        
    };
    
    this.windowResize = function (width, height) {
        document.getElementById(this.containerId).style.width = width + "px";
        document.getElementById(this.containerId).style.height = height + "px";
    }


};




var netgisge = new NetGisGE();


 function initGoogleApi()
 {
    try{
        if(google)
        {
            google.load("earth", "1");
            google.load("maps", "2");
        }
        else
        {
            setTimeout(initGoogleApi, 1000);
        }
    }catch(e){}
    
 }

 initGoogleApi();

function updateSize(id, width, height) {
    if (width == 0)
        return;
    document.getElementById(id).style.width = width - 0 + "px";
    document.getElementById(id).style.height = height - parseInt(document.getElementById(id).style.top) + "px";
    
}

function loadGe(id,xmin, xmax, ymin, ymax) {
    netgisge.load(id, function () {
        if (xmin && xmax && ymin && ymax) {
            netgisge.zoomToExtent(xmin, xmax, ymin, ymax);
        }
    });
}

function zoomToExtent(xmin, xmax, ymin, ymax) {
    netgisge.zoomToExtent(xmin, xmax, ymin, ymax);
}

function hideGe(id) {
    netgisge.hide();
}


function showGe() {
    netgisge.show();
}

function loadKmz(link) {
    try {
        netgisge.loadKMZ(link);
            
    } catch (e) {alert(e); }

}

function flyToFeature(kmlFeature) {
    var aspectRatio = 1;
    var lookAt = computeFitLookAt(netgisge.geInstance, kmlFeature, aspectRatio);
    if (lookAt)
        netgisge.geInstance.getView().setAbstractView(lookAt);
} 

function createPlacemark(desc, lon, lat, range) {
    range = range / parseInt(document.getElementById(netgisge.containerId).style.width);
    range *= 5000;
    netgisge.setCenter(desc, lat, lon);
    netgisge.zoomToPoint(lat, lon,range);
}

function clear() {
    netgisge.clearPlacemarks();
}

function getObjectCoordData(ge, kmlObject) {
    var out = {
        'coords': [],
        'altitudeMode': -1,
        'maxAltitude': -9999
    };

    function pushLatLngAlt(lat, lng, alt) {
        out.coords.push({
            lat: lat,
            lng: lng,
            alt: alt
        });

        out.maxAltitude = Math.max(out.maxAltitude, alt);
    }

    function pushCoord(pointOrCoord) {
        pushLatLngAlt(pointOrCoord.getLatitude(), pointOrCoord.getLongitude(), pointOrCoord.getAltitude());
    }

    function pushChildCall(retval, altitudeMode) {
        out.coords = out.coords.concat(retval.coords);
        out.maxAltitude = Math.max(out.maxAltitude, retval.maxAltitude);

        // stop at first altitudeMode, so if it's already set, don't update it
        if (out.altitudeMode == -1)
            out.altitudeMode = retval.altitudeMode;
    }

    // extract the points from the given object
    if (kmlObject && 'getType' in kmlObject) {
        if (out.altitudeMode == -1 && 'getAltitudeMode' in kmlObject)
            out.altitudeMode = kmlObject.getAltitudeMode();

        switch (kmlObject.getType()) {
            // features 
            case 'KmlFolder':
            case 'KmlDocument':
                var children = kmlObject.getFeatures().getChildNodes();
                var numChildren = children.getLength();
                for (var i = 0; i < numChildren; i++)
                    pushChildCall(getObjectCoordData(ge, children.item(i)));
                break;

            case 'KmlPlacemark':
                if ('getGeometry' in kmlObject)
                    return getObjectCoordData(ge, kmlObject.getGeometry());
                break;

            case 'KmlGroundOverlay':
                var latLonBox = kmlObject.getLatLonBox();
                var alt = kmlObject.getAltitude();
                pushLatLngAlt(latLonBox.getNorth(), latLonBox.getEast(), alt);
                pushLatLngAlt(latLonBox.getNorth(), latLonBox.getWest(), alt);
                pushLatLngAlt(latLonBox.getSouth(), latLonBox.getEast(), alt);
                pushLatLngAlt(latLonBox.getSouth(), latLonBox.getWest(), alt);
                break;

            // geometries 
            case 'KmlMultiGeometry':
                var children = kmlObject.getGeometries().getChildNodes();
                var numChildren = children.getLength();
                for (var i = 0; i < numChildren; i++)
                    pushChildCall(getObjectCoordData(ge, children.item(i)));
                break;

            case 'KmlModel':
                pushCoord(kmlObject.getLocation());
                break;

            case 'KmlPolygon':
                pushChildCall(getObjectCoordData(ge, kmlObject.getOuterBoundary()));
                break;

            case 'KmlLinearRing':
            case 'KmlLineString':
                var coordsObj = kmlObject.getCoordinates();
                var n = coordsObj.getLength();
                for (var i = 0; i < n; i++)
                    pushCoord(coordsObj.get(i));
                break;

            case 'KmlCoord': // coordinates
            case 'KmlLocation': // models
            case 'KmlPoint': // points
                pushCoord(kmlObject);
                break;
        }
    }

    return out;
}

function computeFitLookAt(ge, obj, aspectRatio) {
    var DEGREES = Math.PI / 180;
    var EARTH_RADIUS = 6378137;

    var coordData = getObjectCoordData(ge, obj);

    if ('getAbstractView' in obj) {
        var la = obj.getAbstractView();
        if (la != null)
            return la;
    }

    if (coordData.coords.length) {
        // range calculation -- the hard part
        var center = null;
        var range = 0.0;
        if (coordData.coords.length == 1) {
            center = new google.maps.LatLng(coordData.coords[0].lat, coordData.coords[0].lng);
            range = 1000;
        } else {
            // compute bbox
            var bounds = new google.maps.LatLngBounds();
            for (var i = 0; i < coordData.coords.length; i++)
                bounds.extend(new google.maps.LatLng(coordData.coords[i].lat, coordData.coords[i].lng));

            // find center
            center = bounds.getCenter();
            var sw = bounds.getSouthWest();
            var ne = bounds.getNorthEast();

            var lngSpan = new google.maps.LatLng(center.lat(), sw.lng()).
        distanceFrom(new google.maps.LatLng(center.lat(), ne.lng()));
            var latSpan = new google.maps.LatLng(sw.lat(), center.lng()).
        distanceFrom(new google.maps.LatLng(ne.lat(), center.lng()));

            if (!aspectRatio)
                aspectRatio = 1.0;

            var PAD_FACTOR = 1.5; // add 50% to the computed range for padding
            var beta;

            var aspectUse = Math.max(aspectRatio, Math.min(1.0, lngSpan / latSpan));
            var alpha = (45.0 / (aspectUse + 0.4) - 2.0) * DEGREES; // computed experimentally;

            // create LookAt using distance formula
            if (lngSpan > latSpan) {
                // polygon is wide
                beta = Math.min(90 * DEGREES, alpha + lngSpan / 2 / EARTH_RADIUS);
            } else {
                // polygon is taller
                beta = Math.min(90 * DEGREES, alpha + latSpan / 2 / EARTH_RADIUS);
            }

            range = PAD_FACTOR * EARTH_RADIUS * (Math.sin(beta) *
        Math.sqrt(1 / Math.pow(Math.tan(alpha), 2) + 1) - 1);
        }

        var la = ge.createLookAt('');
        la.set(center.lat(), center.lng(), coordData.maxAltitude, coordData.altitudeMode, 0, 0, range);
        return la;
    }

    return null;
}


