bool WaterElevationLayer::doCreateTile(int level, int tx, int ty, TileStorage::Slot *data)
{
    if (Logger::DEBUG_LOGGER != NULL) {
        ostringstream oss;
        oss << "ElevationRoad tile " << getProducerId() << " " << level << " " << tx << " " << ty;
        Logger::DEBUG_LOGGER->log("DEM", oss.str());
    }
    if (level >= displayLevel) {
        TileCache::Tile *t = graphProducer->findTile(level, tx, ty);
        assert(t != NULL);

        ObjectTileStorage::ObjectSlot *graphData = dynamic_cast<ObjectTileStorage::ObjectSlot*>(t->getData());
        GraphPtr g = graphData->data.cast<Graph>();

        if (g->getCurveCount() == 0) {
            return false;
        }

        ptr<FrameBuffer> fb = SceneManager::getCurrentFrameBuffer();

        vec3d q = getTileCoords(level, tx, ty);
        vec2d nx, ny, lx, ly;
        getDeformParameters(q, nx, ny, lx, ly);

        float scale = 2.0f * (getTileSize() - 1.0f - (2.0f * getTileBorder())) / q.z;

        vec3d tileOffset = vec3d(q.x + q.z / 2.0f, q.y + q.z / 2.0f, scale / getTileSize());
        //tileOffsetU->set(vec3f(q.x + q.z / 2.0f, q.y + q.z / 2.0f, scale / getTileSize()));
        tileOffsetU->set(vec3f(0.0, 0.0, 1.0));

        fb->clear(false, false, true);

        if (g->getAreaCount() > 0) {
            //fillOffsetU->set(vec3f(q.x + q.z / 2.0f, q.y + q.z / 2.0f, scale / getTileSize()));
            fillOffsetU->set(vec3f(0.0, 0.0, 1.0));
            depthU->set(0.02f);
            colorU->set(vec4f(0.0f, 0.0f, 0.0f, 0.0f));

            fb->setDepthTest(true, ALWAYS);
            fb->setColorMask(false, false, false, true);
            fb->setDepthMask(true);

            mesh->setMode(TRIANGLES);
            mesh->clear();
            tess->beginPolygon(mesh);
            ptr<Graph::AreaIterator> ai = g->getAreas();
            while (ai->hasNext()) {
                AreaPtr a = ai->next();
                GraphLayer::drawArea(tileOffset, a, *tess);
            }
            tess->endPolygon();
            fb->draw(fillProg, *mesh);

            riverU->set(1);

            ai = g->getAreas();
            while (ai->hasNext()) {
                AreaPtr a = ai->next();
                bool island = true;
                for (int j = 0; j < a->getCurveCount(); ++j) {
                    int o;
                    island &= (a->getCurve(j, o)->getType() == WaterElevationCurveData::ISLAND);
                    if (!island) {
                        break;
                    }
                }
                for (int j = 0; j < a->getCurveCount(); ++j) {
                    int orientation;
                    CurvePtr p = a->getCurve(j, orientation);
                    if (island) {
                        orientation = 1 - orientation;
                    } else {
                        if (p->getType() == WaterElevationCurveData::ISLAND) {
                            continue;
                        }
                    }
                    if (orientation != 0) {
                        GraphLayer::drawCurve(tileOffset, p, vec4f(0, 12, 1, 2), fb, layerProgram, *(meshuv), &nx, &ny, &lx, &ly);
                    } else {
                        GraphLayer::drawCurve(tileOffset, p, vec4f(0, -12, 1, 2), fb, layerProgram, *(meshuv), &nx, &ny, &lx, &ly);
                    }
                }
            }

            fb->setDepthTest(true, NOTEQUAL);
            fb->setColorMask(false, false, true, false);
            fb->setDepthMask(false);

            riverU->set(2);

            ptr<Graph::CurveIterator> ci = g->getCurves();
            while (ci->hasNext()) {
                CurvePtr c = ci->next();
                float w = c->getWidth();
                float tw = w;
                if (w * scale <= 1 || (c->getParent() == NULL && level != 0) || c->getType() == WaterElevationCurveData::LAKE || c->getType() == WaterElevationCurveData::RIVER || c->getArea1() != NULL) {//== WaterElevationCurveData::RIVER) {
                    continue;
                }
                ElevationCurveData *cData = dynamic_cast<ElevationCurveData*>(findCurveData(c));
                ElevationGraphLayer::drawCurveAltitude(tileOffset, c, cData, tw, tw / w, max(1.0f, 1.0f / scale), false, fb, layerProgram, *meshuv, &nx, &ny, &lx, &ly);
            }
        }

        fb->setColorMask(false, false, true, true);
        fb->setDepthTest(true, LESS);
        fb->setDepthMask(true);

        riverU->set(1);

        ptr<Graph::CurveIterator> ci = g->getCurves();
        while (ci->hasNext()) {
            CurvePtr c = ci->next();
            float cwidth = c->getWidth();
            if (cwidth * scale <= 1 || c->getType() != WaterElevationCurveData::RIVER || (c->getParent() == NULL && level != 0)) {
                continue;
            }

            float w = BASEWIDTH(cwidth, scale);
            float tw = TOTALWIDTH(w);

            ElevationCurveData *cData = dynamic_cast<ElevationCurveData*>(findCurveData(c));
            ElevationGraphLayer::drawCurveAltitude(tileOffset, c, cData, tw, tw / w, max(1.0f, 1.0f / scale), true, fb, layerProgram, *meshuv, &nx, &ny, &lx, &ly);
        }
        fb->setColorMask(true, true, true, true);
    }
    return true;
}