На главную... Продукты | Технологии | Классификаторы | Проекты | Скачать | Цены| Форум | Статьи | Обучение | Контакты

mapAvailableSemanticList & mapAvailableSemanticCode возвращают разные наборы.

Поиск  Пользователи  Правила  Войти
Форум » Linux » Средства разработки ГИС-приложений для Linux
Страницы: 1
RSS
mapAvailableSemanticList & mapAvailableSemanticCode возвращают разные наборы.
 
Доброго времени суток.
Дано:
1. Набор карт, загруженных к базовой.
2. Пользователь создаёт слой sit с неким сторонним классификатором, официальным и в первом приближении соответствующим документации
Код
HMAP PanoramaUtility::createMap(const QString &path, const LayerInfo &info)
{
    QTextCodec* codec = QTextCodec::codecForName( "KOI8-R");
    CREATESITE crs;
    memset( &crs, 0, sizeof( crs));
    crs.Length = sizeof( crs);
    double lat = 384, lon = 512;
    screen2geo( lat, lon);
    lat *= M_PI / 180.;
    lon *= M_PI / 180.;
    crs.AxisMeridian = info.m_axisMeridian == 0 ? lat : info.m_axisMeridian;
    crs.MainPointParallel = info.m_mainParallel == 0 ? lon : info.m_mainParallel;
    crs.Scale = info.m_scale;
    crs.MapType = CK_42;
    crs.MaterialProjection = GAUSSCONFORMAL;
    int maxLen = info.m_name.length() > 31 ? 31 : info.m_name.length();
    memcpy( crs.MapName, codec->fromUnicode( info.m_name).data(), maxLen);

    QDir dr( path);
    if( dr.exists())
    {
        removeDir( path);
    }
    dr.mkpath( path);

    QString layerName = path + "/" + info.m_name + ".sit";
    QFileInfo fli( DEFAULT_OBJECTS_CLASSIFIER);
    QString rscName = path + "/" + fli.fileName();
    QFile fl( DEFAULT_OBJECTS_CLASSIFIER);
    fl.copy( rscName);

   HMAP hMap = mapCreateSite( codec->fromUnicode( layerName).data(),
                              codec->fromUnicode( rscName).data(),
                              &crs);
   return hMap;
}
3. пользователь загружает sit
Код
void PanoramaUtility::openDataToMapPrivate(const QStringList &mapData, int index)
{
    if( m_descriptor == 0) return;
    if( m_mapData.empty()) return;
    if( index < 0) return;
    m_workingLayer = 0;
    QTextCodec *codec = QTextCodec::codecForName( "KOI8-R");
    if( mapOpenSiteForMapEx( m_descriptor, codec->fromUnicode( mapData.at( index)).data(), GENERIC_READ | GENERIC_WRITE, 0) == 0)
    {
        qDebug() << "PanoramaUtility::openDataToMapPrivate ERROR mapOpenSiteForMapEx";
    }
    m_workingLayer = mapGetSiteIdentByName( m_descriptor, codec->fromUnicode( m_mapData.at( index)).data());
    if( m_workingLayer == 0)
    {
        qDebug() << "PanoramaUtility::openDataToMapPrivate ERROR mapGetSiteIdentByName = 0";
    }
}

4. Пользователь создаёт объект по своему выбору из таблиц, полученных из используемого стороннего классификатора (например "Подпись 1.5 син")
Код
bool PanoramaUtility::startNewObject(const QString &newObjectNameFromFilter)
{
    if( m_workingLayer == 0) return false;
    if( m_descriptor == 0) return false;
    QTextCodec *codec = QTextCodec::codecForName( "KOI8-R");
    m_objectToSave.m_clean = true;
    m_objectToSave.m_semList.clear();
    m_objectToSave.m_objectPoints.clear();
    HRSC hRsc = mapGetRscIdent( m_descriptor, m_workingLayer);
    if( hRsc != 0)
    {
        long segmCount = mapGetRscSegmentCount( hRsc);
        for( long i = 0; i < segmCount; i++)
        {
            long objects_in_layer = mapGetRscSegmentObjectCount( hRsc, i);
            for( long j = 1; j <= objects_in_layer; j++)
            {
                QString oNameInLa yer = codec->toUnicode( mapGetRscObjectNameInLayer( hRsc, i, j));
                if( oNameInLayer.isEmpty()) continue;
                if( newObjectNameFromFilter.toLower().compare( oNameInLayer.toLower()) == 0)
                {
                    m_objectToSave.m_excode = mapGetRscObjectExcodeInLayer( hRsc, i, j);
                    m_objectToSave.m_local = mapGetRscObjectLocalInLayer( hRsc, i, j);
                    m_objectToSave.m_objectName = newObjectNameFromFilter;
                    if( m_objectToSave.m_excode == 0) continue;
//For this code no semantic is found at all                                                                                                              <<<<<<<<< тут тоже вопросы, если ответите, будет полезно.
//                    long sheet = mapGetSiteNumber( m_descriptor, m_workingLayer);
//                    HOBJ obj = mapCreateObject( m_descriptor, sheet);
//<<<
                    HOBJ obj = mapCreateSiteObject( m_descriptor, m_workingLayer);
                    if( obj != 0)
                    {
                        m_objectIsCreated = true;
                        if( mapRegisterObject( obj, m_objectToSave.m_excode, m_objectToSave.m_local) != 0)
                        {
                            static long bufCount = 1024;
                            long codeBuffer[ 1024] = { 0};
                            if( mapAvailableMustSemanticList( obj, codeBuffer, bufCount) != 0)                                                          <<<<<<<<<< тут ничего не возвращает, обязательных семантик нет никогда?
                            {
                                for( long t = 0; codeBuffer[ t] != 0; t++)
                                {
                                    if( codeBuffer[ t] != 0)
                                    {
                                        long num = mapAppendSemantic( obj, codeBuffer[ t], "0", 2);
                                        if( num == 0)
                                        {
                                            qDebug() << "PanoramaUtility::startNewObject error MUST mapAppendSemantic" << codeBuffer[ t];
                                        }
                                        else
                                        {
                                            QString semName = codec->toUnicode( mapSemanticName( obj, num));
                                            m_objectToSave.m_semList.append( Semantic( semName, codeBuffer[ t], "0"));
                                            long semClassCount = mapSemanticClassificatorCount( obj, codeBuffer[ t]);
                                            if( semClassCount > 0)
                                            {
                                                for( long k = 1; k <= semClassCount; k++)
                                                {
                                                    //TODO: think about decode table for semantics, based on documents
                                                    QString semClassCodeOrderName = codec->toUnicode( mapSemanticClassificatorName( obj, codeBuffer[ t], k));
                                                    m_objectToSave.m_semList.last().m_availableValues.append( semClassCodeOrderName);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            memset( codeBuffer, 0, bufCount * sizeof( long));
                            long semCode = 0;
                            long count = 1;
                            if( mapAvailableSemanticList( obj, codeBuffer, bufCount) != 0)                                                              <<<<<<<<<<<<<< Возвращает левый набор несуществующих в природе кодов семантик, код добавлен для проверки
                            {
                                for( long kC = 0; codeBuffer[ kC] != 0; kC++)
                                {
                                    qDebug() << "mapAvailableSemanticList: " << codeBuffer[ kC];
                                }
                            }
                            while( ( mapAvailableSemanticCount( obj)) != 0)                                                                             <<<<<<<<<<<<<< Возвращает набор кодов, соответствующих реальным семантикам, но они какие-то странные для
                                                                                                                                          данного набора карт и, походу, зависят от этого самого набора карт, как такое может быть, 
                                                                                                                                         если объект создан для конкретного слоя с конкретным классификатором?
                            {
                                semCode = mapAvailableSemanticCode( obj, count++);
                                if( semCode == 0) break;
                                long num = mapAppendSemantic( obj, semCode, "0", 2);
                                if( num == 0)
                                {
                                    qDebug() << "PanoramaUtility::startNewObject error mapAppendSemantic" << semCode;
                                }
                                else
                                {
                                    QString semName = codec->toUnicode( mapSemanticName( obj, num));
                                    m_objectToSave.m_semList.append( Semantic( semName, semCode, "0"));
                                    long semClassCount = mapSemanticClassificatorCount( obj, semCode);
                                    if( semClassCount > 0)
                                    {
                                        for( long k = 1; k <= semClassCount; k++)
                                        {
                                            //TODO: think about decode table for semantics, based on documents
                                            QString semClassCodeOrderName = codec->toUnicode( mapSemanticClassificatorName( obj, semCode, k));
                                            m_objectToSave.m_semList.last().m_availableValues.append( semClassCodeOrderName);
                                        }
                                    }
                                }
                            }
                            m_objectToSave.m_clean = false;
                        }
                        mapFreeObject( obj);
                    }
                    goto fin;
                }
            }
        }
    }
fin:;
    return true;
    //    qDebug() << "PanoramaUtility::startNewObject" << newObjectNameFromFilter;
}

m_objectToSave потом редактируется пользователем для последующего сохранения объекта в слое.
Вопросы:
1. Правильно ли я создаю слой?
2. Правильно ли я создаю объект для этого слоя?
3. Почему могут отличаться наборы кодов семантик, как указано в комментарии в коде?

Если более конкретно, то:
 

mapAvailableSemanticList:  133148281143305

mapAvailableSemanticList:  133156871108890

mapAvailableSemanticList:  133174050978076

mapAvailableSemanticList:  472446402668

mapAvailableSemanticList:  48546015358089

mapAvailableSemanticList:  20101

mapAvailableSemanticCode:  9

mapAvailableSemanticCode:  31002

mapAvailableSemanticCode:  31004

mapAvailableSemanticCode:  108

mapAvailableSemanticCode:  11401

mapAvailableSemanticCode:  20101

Спасибо.
С уважением,
Александр Лазарев
Изменено: Александр Лазарев - 05.07.2018 10:41:33
 
Может пригодится:
Код
**
 * @brief Описание семантической характеристики объекта векторной карты.
 *
 * Позволяет узнать:
 *  - внешний код семантики (классификационный код)
 *  - тип значения gis::common::SemanticValueType
 *  - название
 *  - ключ (короткое название)
 *  - интервал значений (для числовых характерстик)
 *  - значение по-умолчанию (для числовых характеристик)
 *  - единицу измерения
 *
 * Является обёрткой над RSCSEMANTICEX
 */
class RscSemanticInfo
{
public:
    /// Наиболее распространённые семантики классификатора ******
    /// Метка TCODE означает, что семантика имеет тип TCODE (перечисление)
    enum class FrqntlyUsedCodes: long{
        AbsoluteHeight = 4,                 ///< абсолютная высота
        OwnName = 9,                        ///< собственное название
        TypeOfStateTCODE = 1100,            ///< гос-ная принадлежность
        TypeOfActionTCODE = 1200,           ///< характер действия
        ObjColorPropertyTCODE = 1300,       ///< признак цвета объекта
        ObjLinePropertyTCODE = 1400,        ///< признак типа линни объекта
        TextInsideObj = 5400,               ///< произвольная надпись внутри знака
        Key**** = 11525,                    ///< код ****
        LocalityName = 20101,               ///< название населённого пункта
        ViewScale = 31001,                  ///< масштаб отображения знака (от 0.00 до 500.00%)
        ObjColorRGB = 31002,                ///< цвет отображения знака в RGB (при задании семантики требуется использовать QColor)
        FontHeight = 31003,                 ///< Высота шрифта, от 0.00 до 20.00
        FontName = 31004,                   ///< Название шрифта ("Arial", "Courier", и т.д.)
        Other = 0                           ///< Прочие семантики
    };
    RscSemanticInfo();
    RscSemanticInfo(const RscSemanticInfo& other);
    RscSemanticInfo& operator=(const RscSemanticInfo& other);
    virtual ~RscSemanticInfo(){}

    operator RSCSEMANTICEX*(){
        return &m_info;
    }

    /// Внешний код семантики
    long int  getExCode() const;

    FrqntlyUsedCodes getFrqCode() const;

    /// Тип значения семантики
    gis::common::SemanticValueType getValueType() const;

    ///Разрешается ли повторение
    bool      canRepeat() const;

    ///Важность семантики для объектов,
    ///допустимая или обязательный семантика
    gis::common::SemanticUsageInObject getImportance() const;

    ///Служебная ли семантика.
    /// Служебные семантики допустимы для всех объектов
    bool      isService() const;

    /// Название семантики
    QString   getName() const;
    /// Единица измерения
    QString   getUnit() const;

    /// Минимальное значение (для числовых характеристик)
    double    getMinValue() const;
    /// Значение по-умолчанию (для числовых характеристик)
    double    getDefaultValue() const;
    /// Максимальное значение (для числовых характеристик)
    double    getMaxValue() const;

    /// Ключ семантики (короткое имя)
    QString   getKey() const;

    QVariant  getEmptyValue() const;

    /**
     * @brief получить описание значений для семантики типа TCODE
     * @return пустой словарь, если тип семантики не TCODE
     */
    const QMap<long int, QString> getValueMap() const;


    friend class VMapClassifier;

private:
    RSCSEMANTICEX m_info;
    QMap<long int, QString> m_tcodeValueMap;
};


/**
 * @brief Описание объекта из классификатора
 *
 * Обёртка над RSCOBJECT
 */
class RscObjectInfo
{
public:
    RscObjectInfo(const QString& key = "", const QList<RscSemanticInfo>& semantics = {});
    RscObjectInfo(const RscObjectInfo& other);
    RscObjectInfo& operator=(const RscObjectInfo& other);
    virtual ~RscObjectInfo(){}

    operator RSCOBJECT*(){
        return &m_obj;
    }

    /// классификационный код
    unsigned long getCode() const;
    /// характер локализации
    gis::common::RscObjectLocal getLocal() const;
    /// номер слоя в классификаторе
    unsigned long getRscLayerIndex() const;
    /// true - объект масштабируется, иначе не масштабируется
    bool          isScaled() const;
    /// направление цифрования объекта
    gis::common::RscObjectDirect getDirect() const;
    /// нижняя граница видимости (знаменатель масштаба)
    unsigned long getBotScale() const;
    /// верхняя граница видимости (знаменатель масштаба)
    unsigned long getTopScale() const;
    /// название объекта
    QString       getName() const;

    ///уникальный символьный ключ объекта в классификаторе
    const QString& getKey() const;

    ///получить список семантик, поддерживаемых данным объектом
    const QList<RscSemanticInfo>& getSemantics() const;

private:
    RSCOBJECT m_obj;
    QString   m_key;
    QList<RscSemanticInfo> m_semantics;
};

//Запрос описание объекта из классификатора
virtual RscObjectInfo getObjectInfo(const QString& rscObjKey, bool* ok = nullptr) const = 0;


RscObjectInfo VMapClassifier::getObjectInfo(const QString &rscObjKey, bool *ok) const
{
    RscObjectInfo ret;
    if (!isValid()){
        if (ok){
            *ok = false;
        }
        return ret;
    }
    QByteArray koi8r = gis::common::convertStringToKOI8_R(rscObjKey.trimmed());
    long incode = mapGetRscObjectKeyIncode(m_rsc, koi8r.constData());
    if (getObjectByIncode(incode, ret)){
        if (ok){
            *ok = true;
        }
        return ret;
    }
    if (ok){
        *ok = false;
    }
    return ret;
}


bool VMapClassifier::getObjectByIncode(long incode,
                                       RscObjectInfo &objInfo) const
{
    QString objKey = gis::common::parseStringFromKOI8_R(mapGetRscObjectKey(m_rsc, incode));
    if (objKey.isEmpty()){
        return false;
    }
    QList<RscSemanticInfo> rscSemantics;
#define MAX_CODE_COUNT 64
    long codeList[MAX_CODE_COUNT];
    long codeCnt = mapGetRscSemanticObjectCodeList(m_rsc, incode, codeList,
                                                   MAX_CODE_COUNT);
    for (long i = 0; i < codeCnt; i++){
        RscSemanticInfo sInfo;
        if (readSemanticInfoByCode(sInfo, codeList[i])){
            rscSemantics << sInfo;
        }
    }
#undef MAX_CODE_COUNT
    RscObjectInfo ret{objKey, rscSemantics};
    long rc = mapGetRscObject(m_rsc, incode, ret);
    if (rc != incode){
        return false;
    }
    objInfo = ret;
    return true;
}


bool VMapClassifier::readSemanticInfoByCode(RscSemanticInfo &info, long semExCode) const
{
    if (!isValid()){
        return false;
    }
    long rc = mapGetRscSemanticExByCode(m_rsc, info, semExCode);
    if (0 == rc){
        return false;
    }
    info.m_tcodeValueMap = calcSemanticValueMapForTCODE(info);
    return true;
}

Данных из RscObjInfo достаточно для создания объекта, а дальше остаётся только заполнить метрику и установить семантики из списка поддерживаемых.

Объекта сначала ищется в классификаторе по ключу, а потом по его описанию создаётся

Читать начиная с
Цитата
RscObjectInfo VMapClassifier::getObjectInfo(const QString &rscObjKey, bool *ok) const
 
Здравствуйте!
Цитата
Александр Лазарев написал:
1. Правильно ли я создаю слой?
2. Правильно ли я создаю объект для этого слоя?
Концептуально, функции используются правильно (детали записи значений в параметры не анализировал).

Цитата
Александр Лазарев написал:
3. Почему могут отличаться наборы кодов семантик, как указано в комментарии в коде?
Вы не могли бы немного разгрузить пример, чтобы можно было сфокусироваться именно на участке кода, относящемся к вопросу (в идеале, чтобы его можно было воспроизвести как тестовый пример).
 
Цитата
Александр Савелов написал:
Здравствуйте!
Цитата
 Александр Лазарев  написал:
1. Правильно ли я создаю слой?
2. Правильно ли я создаю объект для этого слоя?
Концептуально, функции используются правильно (детали записи значений в параметры не анализировал).

Цитата
 Александр Лазарев  написал:
3. Почему могут отличаться наборы кодов семантик, как указано в комментарии в коде?
Вы не могли бы немного разгрузить пример, чтобы можно было сфокусироваться именно на участке кода, относящемся к вопросу (в идеале, чтобы его можно было воспроизвести как тестовый пример).
На самом деле вышеприведённый код можно использовать напрямую, я вам только дам сейчас определения типов:
Код
    HMAP                        m_descriptor; дескриптор открытого набора карт
    HSITE                       m_workingLayer; дескриптор созданного слоя при помощи createMap

struct LayerInfo
{
    QString     m_name;
    int         m_scale;
    double      m_cLat,
                m_cLon;
    double      m_axisMeridian,
                m_mainParallel;
    LayerInfo() :m_scale(0), m_cLat( 0), m_cLon( 0), m_axisMeridian( 0), m_mainParallel( 0){}
};

struct Semantic
{
    QString             m_semName;
    long                m_semCode;
    QString             m_semValue;
    QStringList         m_availableValues;
    Semantic(){}
    Semantic( const QString& semName, const long& code, const QString& value)
        : m_semName( semName), m_semCode( code), m_semValue( value){}
    void clear() { m_availableValues.clear();}
};

    struct CreatedObjectInfo
    {
        bool                    m_clean;
        QString                 m_objectName;
        long                    m_excode,
                                m_local;
        QVector< Semantic>      m_semList;
        QVector< QPointF>       m_objectPoints;
    };

    CreatedObjectInfo           m_objectToSave;

Используется стандартный классификатор operator.rsc для нанесения военно-тактической обстановки. Далее выполняются действия по пунктам, как я расписал в своём первом сообщении.
Просто разгружать делее почти некуда, так или иначе потребуется загруженный базовый набор карт, на котором необходимо создать слой sit с классификатором, и любой из текстовых идентификаторов объекта из классификатора для заполнения полей объекта.
 
Здравствуйте!

В реализации функции mapAvailableSemanticList допущена ошибка, связанная с неправильным анализом буфера семантик.
В частности, если реализовать заполнение и обход следующим образом, то список семантик получится идентичным полученному с помощью функции
mapAvailableSemanticCode:
Код
  int availableSemanticList[1024];
  memset(availableSemanticList, 0, sizeof(availableSemanticList));
  long availableSemanticCount = mapAvailableSemanticList(objectHandle, (long int*)availableSemanticList, sizeof(availableSemanticList)/sizeof(int));
  std::cout << "availableSemanticCount: " << availableSemanticCount << std::endl;

  int semanticNumber = 0;
  while (availableSemanticList[semanticNumber])
  {
    std::cout << "semantic code: " << availableSemanticList[semanticNumber] << std::endl;
    semanticNumber++;
  }
Функцию mapAvailableSemanticList исправим - спасибо!
Страницы: 1
Читают тему (гостей: 1)



© КБ Панорама, 1991-2024

Регистрируясь или авторизуясь на форуме, Вы соглашаетесь с Политикой конфиденциальности