Здравствуйте! Разрабатываю прикладную задачу - SDK Панорамы #7, MSVS.Net. При работе с DIR обнаружилась проблема - могу получить доступ только к объектам первого листа.
Код
for( long int list = 1; list <= mapGetListCount( myMap ); list++ )
{
long int currentObject = 0;
for( long int object = 1; object <= mapGetObjectCount( myMap, list ); object++ )
{
if( !currentObject )
{//-- надо инициализировать новый объект:
currentObject = mapCreateObject( myMap, list ); //-- <*>
}
else
{//-- объект инициализирован на предыдущей итерации, надо очистить:
mapClearObject( currentObject );
}
isCorrectObject = mapReadObjectByNumber( myMap, 0, currentObject, list, object );
if( isCorrectObject > 1 && currentObject )
{//-- объект считался корректно и он не удален:
...
doSmth(); //-- объект может быть уделён -тогда currentObject явно обнулится.
...
}
}
mapAdjustData( myMap );
}
<*> если list != 1 - mapCreateObject( myMap, list ) возвращает 0. Т.е. с доступом, как таковым, наверное проблем не будет, но весь функционал, получающий в параметрах идентификатор существующего объекта, не доступен. Куда копать?
1. В приведенном коде я не заметил вызова функции mapFreeObject:
mapCreateObject - размещение объекта в памяти mapFreeObject - освобождение из памяти
Переменную currentObject лучше объявить выше внешнего цикла, удалить - после внешнего цикла: if (currentObject) mapFreeObject(currentObject);
2. Создать объект лучше выше внешнего цикла (номер листа не имеет значения): mapCreateObject(myMap, 1);
3. Функция mapReadObjectByNumber размешает в currentObject объект текущего листа. Предварительная очистка объекта в памяти (mapClearObject) не требуется. Обычно функция mapClearObject используется для очистки данных объекта (метрики и семантики) при формировании объекта с нуля (добавление точек метрики, добавление семантики).
4. После редактирования объекта в памяти необходимо записать объект в карту (mapCommitObject).
5. Приведенный код может быть использован только для первой карты списка открытых данных. Для обработки всех карт списка открытых данных используются функции mapGetSiteCount, mapGetSiteNumber. Организуется дополнительный цикл.
Alexander Kruzhkov пишет: 5. Приведенный код может быть использован только для первой карты списка открытых данных. Для обработки всех карт списка открытых данных используются функции mapGetSiteCount, mapGetSiteNumber. Организуется дополнительный цикл.
АПИ вида map*Site*(...); позволяет работать с пользовательскими картами, которые в данной ситуации не учавствуют. Проблема проявляется после создания новых объектов - если в текущем листе увеличивается значение mapGetObjectCount, значит, в следующем листе mapCreateObject будет возвращать 0. Мож, неправильно создаю объекты?
1. Отсутствует вызов функции mapAppendPointPlane (ввод метрики подписи - 2 точки). К сожалению, по приведенным фрагментам кода не понял алгоритма. Поэтому дополню: 2. Если объект считан с карты, отредактирован и записан функцией mapCommitObject, то выполнится обновление объекта карты на том листе, с которого он считан. 3. Если объект создается "с нуля", то можно воспользоваться функцией mapCommitWithPlaceForList или mapCommitWithPlaceAsNew (выбор листа выполняется автоматически). Объект запишется в тот лист района, на который попадает его метрика:
Код
// Создается один раз (на все листы)
HOBJ signatureObj = mapCreateObject( myMap, 1, IDFLOAT2, 1);
for (...)
{
// Очистить все данные объекта
mapClearObject(...);
//-- заполняем подпись:
mapAppendPointPlane(...);
mapAppendPointPlane(...);
mapPutText( signatureObj, text, 0 );
mapAppendSemantic( signatureObj, semCode, text, MAX_PATH );
//-- сохраняем в карте:
mapRegisterObject( signatureObj, __SIGNATURE_EXCODE, LOCAL_TITLE );
mapCommitObjectWithPlaceAsNew( signatureObj );
}
//-- освобождаем память:
mapFreeObject( signatureObj );
Код 2: Похоже на рабочий фрагмент текста. Большинство задач по созданию и редактированию объектов типичны, но как правило, имеют особенности. Не имея полного текста функции, сложно судить о качестве ее работы.