geos::geom::Geometry* GeoJSONReader::read(Handle<Value> value) { if (!value->IsObject()) { throw "GeoJSON must be an instance of Object"; } Isolate* isolate = Isolate::GetCurrent(); HandleScope scope(isolate); Handle<Object> obj = Handle<Object>::Cast(value); Handle<String> typeKey = String::NewFromUtf8(isolate, "type"); if (!obj->HasOwnProperty(typeKey)) { throw "Property \"type\" is missing"; } std::string string = *String::Utf8Value(obj->Get(typeKey)->ToString()); geos::geom::Geometry* g; try { if (string == "Point") { g = getPoint(getCoordsArray(obj)); } else if (string == "LineString") { g = getLineString(getCoordsArray(obj)); } else if (string == "Polygon") { g = getPolygon(getCoordsArray(obj)); } else if (string == "MultiPoint") { g = getMultiPoint(getCoordsArray(obj)); } else if (string == "MultiLineString") { g = getMultiLineString(getCoordsArray(obj)); } else if (string == "MultiPolygon") { g = getMultiPolygon(getCoordsArray(obj)); } else if (string == "GeometryCollection") { g = getGeometryCollection(getGeomsArray(obj)); } else { throw "Property \"type\" has a value that is not supported or allowed"; } } catch (...) { throw; } return g; }
Handle<Array> GeoJSONReader::getGeomsArray(Handle<Object> geojson) { Isolate* isolate = Isolate::GetCurrent(); Handle<String> geomsKey = String::NewFromUtf8(isolate, "geometries"); if (!geojson->HasOwnProperty(geomsKey)) throw "Property \"geometries\" is missing"; Handle<Value> geoms = geojson->Get(geomsKey); if ( !geoms->IsArray() ) throw "Property \"geometries\" must be an instance of Array"; return Handle<Array>::Cast(geoms); }
Handle<Value> GeoJSONReader::getCoordsArray(Handle<Object> geojson) { Isolate* isolate = Isolate::GetCurrent(); Handle<String> coordsKey = String::NewFromUtf8(isolate, "coordinates"); if (!geojson->HasOwnProperty(coordsKey)) throw "Property \"coordinates\" is missing"; Handle<Value> coords = geojson->Get(coordsKey); if ( !coords->IsArray() && !coords->IsNull() && !coords->IsUndefined() ) throw "Property \"coordinates\" must be an instance of Array or null"; return coords; }
Handle<Object> MetadataNode::GetImplementationObject(const Handle<Object>& object) { DEBUG_WRITE("GetImplementationObject called on object:%d", object->GetIdentityHash()); auto target = object; Handle<Value> currentPrototype = target; Handle<Object> implementationObject; implementationObject = object->GetHiddenValue(ConvertToV8String("t::implObj")).As<Object>(); if (!implementationObject.IsEmpty()) { return implementationObject; } if (object->HasOwnProperty(V8StringConstants::GetIsPrototypeImplementationObject())) { auto v8Prototype = V8StringConstants::GetPrototype(); if (!object->HasOwnProperty(v8Prototype)) { return Handle<Object>(); } DEBUG_WRITE("GetImplementationObject returning the prototype of the object :%d", object->GetIdentityHash()); return object->Get(v8Prototype).As<Object>(); } auto obj = V8GetHiddenValue(object, "t::ActivityImplementationObject").As<Object>(); if (!obj.IsEmpty()) { DEBUG_WRITE("GetImplementationObject returning ActivityImplementationObject property on object: %d", object->GetIdentityHash()); return obj; } Handle<Value> lastPrototype; bool prototypeCycleDetected = false; while (implementationObject.IsEmpty()) { // currentPrototype = currentPrototype.As<Object>()->GetPrototype(); if (currentPrototype->IsNull()) break; //DEBUG_WRITE("GetImplementationObject currentPrototypeObject:%d", (currentPrototype.IsEmpty() || currentPrototype.As<Object>().IsEmpty()) ? -1 : currentPrototype.As<Object>()->GetIdentityHash()); //DEBUG_WRITE("GetImplementationObject lastPrototypeObject:%d", (lastPrototype.IsEmpty() || lastPrototype.As<Object>().IsEmpty()) ? -1 : lastPrototype.As<Object>()->GetIdentityHash()); if (currentPrototype == lastPrototype) { auto abovePrototype = currentPrototype.As<Object>()->GetPrototype(); prototypeCycleDetected = abovePrototype == currentPrototype; } if (currentPrototype.IsEmpty() || prototypeCycleDetected) { //Handle<Value> abovePrototype = currentPrototype.As<Object>()->GetPrototype(); //DEBUG_WRITE("GetImplementationObject not found since cycle parents reached abovePrototype:%d", (abovePrototype.IsEmpty() || abovePrototype.As<Object>().IsEmpty()) ? -1 : abovePrototype.As<Object>()->GetIdentityHash()); return Handle<Object>(); } else { auto value = currentPrototype.As<Object>()->GetHiddenValue(V8StringConstants::GetClassImplementationObject()); if (!value.IsEmpty()) { implementationObject = currentPrototype.As<Object>(); } } lastPrototype = currentPrototype; } return implementationObject; }
Handle<Value> LineStringPoints::add(const Arguments& args) { HandleScope scope; Handle<Object> parent = args.This()->GetHiddenValue(String::NewSymbol("parent_"))->ToObject(); LineString *geom = ObjectWrap::Unwrap<LineString>(parent); int n = args.Length(); if(n == 0) { return NODE_THROW("Point must be given"); } else if(n == 1) { if(!args[0]->IsObject()) { return NODE_THROW("Point, object, or array of points expected"); } if(IS_WRAPPED(args[0], Point)){ //set from Point object Point* pt = ObjectWrap::Unwrap<Point>(args[0]->ToObject()); geom->get()->addPoint(pt->get()); } else if (args[0]->IsArray()) { //set from array of points Handle<Array> array = Handle<Array>::Cast(args[0]); int length = array->Length(); for (int i = 0; i < length; i++){ Handle<Value> element = array->Get(i); if(!element->IsObject()) { return NODE_THROW("All points must be Point objects or objects"); } Handle<Object> element_obj = element->ToObject(); if(IS_WRAPPED(element_obj, Point)){ //set from Point object Point* pt = ObjectWrap::Unwrap<Point>(element_obj); geom->get()->addPoint(pt->get()); } else { //set from object {x: 0, y: 5} double x, y; NODE_DOUBLE_FROM_OBJ(element_obj, "x", x); NODE_DOUBLE_FROM_OBJ(element_obj, "y", y); Handle<String> z_prop_name = String::NewSymbol("z"); if (element_obj->HasOwnProperty(z_prop_name)) { Handle<Value> z_val = element_obj->Get(z_prop_name); if (!z_val->IsNumber()) { return NODE_THROW("z property must be number"); } geom->get()->addPoint(x, y, z_val->NumberValue()); } else { geom->get()->addPoint(x, y); } } } } else { //set from object {x: 0, y: 5} Handle<Object> obj = args[0]->ToObject(); double x, y; NODE_DOUBLE_FROM_OBJ(obj, "x", x); NODE_DOUBLE_FROM_OBJ(obj, "y", y); Handle<String> z_prop_name = String::NewSymbol("z"); if (obj->HasOwnProperty(z_prop_name)) { Handle<Value> z_val = obj->Get(z_prop_name); if (!z_val->IsNumber()) { return NODE_THROW("z property must be number"); } geom->get()->addPoint(x, y, z_val->NumberValue()); } else { geom->get()->addPoint(x, y); } } } else { //set x, y, z from numeric arguments if(!args[0]->IsNumber()){ return NODE_THROW("Number expected for first argument"); } if(!args[1]->IsNumber()){ return NODE_THROW("Number expected for second argument"); } if(n == 2){ geom->get()->addPoint(args[0]->NumberValue(), args[1]->NumberValue()); } else { if(!args[2]->IsNumber()){ return NODE_THROW("Number expected for third argument"); } geom->get()->addPoint(args[0]->NumberValue(), args[1]->NumberValue(), args[2]->NumberValue()); } } return Undefined(); }
Handle<Value> LineStringPoints::set(const Arguments& args) { HandleScope scope; Handle<Object> parent = args.This()->GetHiddenValue(String::NewSymbol("parent_"))->ToObject(); LineString *geom = ObjectWrap::Unwrap<LineString>(parent); int i; NODE_ARG_INT(0, "index", i); if(i < 0 || i >= geom->get()->getNumPoints()) { return NODE_THROW("Point index out of range"); } int n = args.Length() - 1; if(n == 0) { return NODE_THROW("Point must be given"); } else if(n == 1) { if(!args[1]->IsObject()) { return NODE_THROW("Point or object expected for second argument"); } if(IS_WRAPPED(args[1], Point)){ //set from Point object Point* pt = ObjectWrap::Unwrap<Point>(args[1]->ToObject()); geom->get()->setPoint(i, pt->get()); } else { Handle<Object> obj = args[1]->ToObject(); //set from object {x: 0, y: 5} double x, y; NODE_DOUBLE_FROM_OBJ(obj, "x", x); NODE_DOUBLE_FROM_OBJ(obj, "y", y); Handle<String> z_prop_name = String::NewSymbol("z"); if (obj->HasOwnProperty(z_prop_name)) { Handle<Value> z_val = obj->Get(z_prop_name); if (!z_val->IsNumber()) { return NODE_THROW("z property must be number"); } geom->get()->setPoint(i, x, y, z_val->NumberValue()); } else { geom->get()->setPoint(i, x, y); } } } else { //set x, y, z from numeric arguments if(!args[1]->IsNumber()){ return NODE_THROW("Number expected for second argument"); } if(!args[2]->IsNumber()){ return NODE_THROW("Number expected for third argument"); } if(n == 2){ geom->get()->setPoint(i, args[1]->NumberValue(), args[2]->NumberValue()); } else { if(!args[3]->IsNumber()){ return NODE_THROW("Number expected for fourth argument"); } geom->get()->setPoint(i, args[1]->NumberValue(), args[2]->NumberValue(), args[3]->NumberValue()); } } return Undefined(); }