/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2008 Robert Osfield * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or * (at your option) any later version. The full license is in LICENSE file * included with this distribution, and on the openscenegraph.org website. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * OpenSceneGraph Public License for more details. */ #include "Exception.h" #include "Layer.h" #include "Locator.h" #include "Object.h" #include "Locator.h" #include "ImageLayer.h" #include "HeightFieldLayer.h" #include "CompositeLayer.h" #include "SwitchLayer.h" #include using namespace ive; void Layer::write(DataOutputStream* out) { // Write Layer's identification. out->writeInt(IVELAYER); // If the osg class is inherited by any other class we should also write this to file. osg::Object* object = dynamic_cast(this); if (object) ((ive::Object*)(object))->write(out); else out_THROW_EXCEPTION("Layer::write(): Could not cast this osgLayer::Layer to an osg::Object."); if (out->getVersion() >= VERSION_0023) { out->writeLocator(getLocator()); if (out->getVersion() >= VERSION_0034) { out->writeUInt(getMinFilter()); out->writeUInt(getMagFilter()); } else { out->writeUInt((getMagFilter()==osg::Texture::LINEAR) ? 1 : 0); } } else { LayerHelper helper; helper.writeLocator(out, getLocator()); } out->writeUInt(getMinLevel()); out->writeUInt(getMaxLevel()); if (out->getVersion() >= VERSION_0027) { writeValidDataOperator(out,getValidDataOperator()); } } void Layer::read(DataInputStream* in) { // Peek on Layer's identification. int id = in->peekInt(); if (id != IVELAYER) in_THROW_EXCEPTION("Layer::read(): Expected Layer identification."); // Read Layer's identification. id = in->readInt(); // If the osg class is inherited by any other class we should also read this from file. osg::Object* object = dynamic_cast(this); if(object) ((ive::Object*)(object))->read(in); else in_THROW_EXCEPTION("Layer::read(): Could not cast this osgLayer::Layer to an osg::Group."); if (in->getVersion() >= VERSION_0023) { setLocator(in->readLocator()); if (in->getVersion() >= VERSION_0034) { setMinFilter(osg::Texture::FilterMode(in->readUInt())); setMagFilter(osg::Texture::FilterMode(in->readUInt())); } else { setMagFilter(in->readUInt()==0 ? osg::Texture::NEAREST : osg::Texture::LINEAR); } } else { LayerHelper helper; setLocator(helper.readLocator(in)); } setMinLevel(in->readUInt()); setMaxLevel(in->readUInt()); if (in->getVersion() >= VERSION_0027) { setValidDataOperator(readValidDataOperator(in)); } } void LayerHelper::writeLayer(DataOutputStream* out, osgTerrain::Layer* layer) { if (layer) { out->writeBool(true); if (dynamic_cast(layer)) { ((ive::HeightFieldLayer*)(layer))->write(out); } else if (dynamic_cast(layer)) { ((ive::ImageLayer*)(layer))->write(out); } else if (dynamic_cast(layer)) { ((ive::SwitchLayer*)(layer))->write(out); } else if (dynamic_cast(layer)) { ((ive::CompositeLayer*)(layer))->write(out); } else if (dynamic_cast(layer)) { out->writeInt(IVEPROXYLAYER); out->writeString(layer->getFileName()); osgTerrain::Locator* locator = layer->getLocator(); bool writeOutLocator = locator && !locator->getDefinedInFile(); writeLocator(out, writeOutLocator ? locator : 0 ); out->writeUInt(layer->getMinLevel()); out->writeUInt(layer->getMaxLevel()); } } else { out->writeBool(false); } } osgTerrain::Layer* LayerHelper::readLayer(DataInputStream* in) { bool layerExist = in->readBool(); if (!layerExist) return 0; int id = in->peekInt(); if (id==IVEHEIGHTFIELDLAYER) { osgTerrain::HeightFieldLayer* layer = new osgTerrain::HeightFieldLayer; ((ive::HeightFieldLayer*)(layer))->read(in); return layer; } else if (id==IVEIMAGELAYER) { osgTerrain::ImageLayer* layer = new osgTerrain::ImageLayer; ((ive::ImageLayer*)(layer))->read(in); return layer; } else if (id==IVESWITCHLAYER) { osgTerrain::SwitchLayer* layer = new osgTerrain::SwitchLayer; ((ive::SwitchLayer*)(layer))->read(in); return layer; } else if (id==IVECOMPOSITELAYER) { osgTerrain::CompositeLayer* layer = new osgTerrain::CompositeLayer; ((ive::CompositeLayer*)(layer))->read(in); return layer; } else if (id==IVEPROXYLAYER) { std::string filename = in->readString(); osg::ref_ptr proxyLayer = osgDB::readRefFile(filename+".gdal"); osg::ref_ptr locator = readLocator(in); unsigned int minLevel = in->readUInt(); unsigned int maxLevel = in->readUInt(); if (proxyLayer) { if (locator.valid()) proxyLayer->setLocator(locator.get()); proxyLayer->setMinLevel(minLevel); proxyLayer->setMaxLevel(maxLevel); } return proxyLayer.release(); } return new osgTerrain::ImageLayer; } void LayerHelper::writeLocator(DataOutputStream* out, osgTerrain::Locator* locator) { if (locator) { out->writeBool(true); ((ive::Locator*)(locator))->write(out); } else { out->writeBool(false); } } osgTerrain::Locator* LayerHelper::readLocator(DataInputStream* in) { bool locatorExist = in->readBool(); if (!locatorExist) return 0; osgTerrain::Locator* locator = new osgTerrain::Locator; ((ive::Locator*)(locator))->read(in); return locator; } void Layer::writeValidDataOperator(DataOutputStream* out, osgTerrain::ValidDataOperator* validDataOperator) { if (validDataOperator) { out->writeBool(true); osgTerrain::ValidRange* validRange = dynamic_cast(validDataOperator); if (validRange) { out->writeInt(IVEVALIDRANGE); out->writeFloat(validRange->getMinValue()); out->writeFloat(validRange->getMaxValue()); } else { osgTerrain::NoDataValue* noDataValue = dynamic_cast(validDataOperator); if (noDataValue) { out->writeInt(IVENODATAVALUE); out->writeFloat(noDataValue->getValue()); } } } else { out->writeBool(false); } } osgTerrain::ValidDataOperator* Layer::readValidDataOperator(DataInputStream* in) { bool hasOperator = in->readBool(); if (!hasOperator) return 0; int id = in->peekInt(); if (id==IVEVALIDRANGE) { id = in->readInt(); float minValue = in->readFloat(); float maxValue = in->readFloat(); return new osgTerrain::ValidRange(minValue,maxValue); } else if (id==IVENODATAVALUE) { id = in->readInt(); float value = in->readFloat(); return new osgTerrain::NoDataValue(value); } else { return 0; } }